zoukankan      html  css  js  c++  java
  • AJAX异步、sweetalert、Cookie和Session初识

    复制代码
    一、AJAX的异步示例
    1. urls.py
    
    from django.conf.urls import url
    from apptest import views
    
    
    urlpatterns = [
        url(r'^atest/', views.atest),
        url(r'^ajax1/', views.ajax1),
        url(r'^ajax2/', views.ajax2),
    ]
    View Code


    2. atext.HTML
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta http-equiv="content-type" charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    
    <body>
    <div>
        <input type="text" id="i1">
        <button id="b1">按钮1</button>
    </div>
    
    <div>
        <input type="text" id="i2">
        <button id="b2">按钮2</button>
    </div>
    
    
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script type="text/javascript">
        // 点击按钮1给ajax1发送get请求
        $("#b1").click(function () {
            $.ajax({
                url: '/ajax1/',
                type: 'get',
                success: function (res) {
                    $("#i1").val(res)
                }
            })
        });
    
        // 点击按钮2给ajax2发送get请求
            $("#b2").click(function () {
            $.ajax({
                url: '/ajax2/',
                type: 'get',
                success: function (res) {
                    $("#i2").val(res)
                }
            })
        });
    
    
    </script>
    
    </body>
    </html>
    View Code


    3.views.py
    def atest(request):
        return render(request, 'atest.html')
    
    
    def ajax1(request):
        import time
        time.sleep(3) # 模仿网络堵塞的时候
        return HttpResponse('ajax1')
    
    
    def ajax2(request):
        return HttpResponse('ajax2')
    View Code
    
    
    
    4.结果解析
    在页面中首先点击按钮1,然后立刻点击按钮2,由于按钮1的网络堵塞(我用time模块模拟的堵塞),服务端会延迟几秒才返回响应,
    如果AJAX的请求是同步的,那么按钮2的请求必须要等到按钮1响应后才会被处理,而从我们这个简单的实例中可以看出,
    按钮1没有得到响应的时候,按钮2已经得到响应结果了,因此可以看出AJAX的请求是异步的。
    
    
    
    二、Sweetalert示例
    1、Bootstrap-sweetalert
        项目下载
        https://github.com/lipis/bootstrap-sweetalert
    
        使用方法
        https://lipis.github.io/bootstrap-sweetalert/
    
    使用步骤
        1. 下载插件
        2. 解压 --> 拿到dist目录下的内容
        3. 拷贝到Django项目的static文件夹下
        4. 在HTML页面上导入sweetalert.css和sweetalert.js
    
    2、示例(此处只是实现了删除的Sweetalert)
    1.index页面代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
        {% load static %}
        <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.css' %}">
        <link rel="stylesheet" href="{% static 'sweetalert/sweetalert.css' %}">
        <link rel="stylesheet" href="{% static 'font-awesome-4.7.0/css/font-awesome.css' %}">
        <style>
            div.sweet-alert.showSweetAlert h2 {
                margin-top: 30px;
            }
        </style>
    </head>
    <body>
    
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3" style="margin-top: 70px">
                <a href="/logout/">注销</a>
                <table class="table table-bordered table-striped">
                    <thead>
                    <tr>
                        <th>序号</th>
                        <th>出版社名称</th>
                        <th>出版社地址</th>
                        <th>操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for publisher in publisher_list %}
                        <tr pid="{{ publisher.id }}">
                            <td>{{ forloop.counter }}</td>
                            <td>{{ publisher.pname }}</td>
                            <td>{{ publisher.addr }}</td>
                            <td>
                                <button class="btn btn-warning">
                                    <i class="fa fa-pencil"></i>
                                    编辑
                                </button>
                                <button class="btn btn-danger delete-btn">
                                    <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
                                    删除
                                </button>
                            </td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    
    {% csrf_token %}
    
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script>
    <script src="{% static 'sweetalert/sweetalert.js' %}"></script>
    <script>
        $('.delete-btn').click(function () {
            var deleteId = $(this).parent().parent().attr('pid');
            console.log(deleteId,typeof deleteId);
            swal({
                    title: "确定要删除吗?",
                    text: "删除后无法找回",
                    type: "warning",  // success/info/warning/error
                    showCancelButton: true,
                    confirmButtonClass: "btn-danger",
                    confirmButtonText: "删除",
                    cancelButtonText: "取消",
                    showLoaderOnConfirm: true,  // 点击确认按钮之后会有一个加载的动画
                    closeOnConfirm: false
                },
                function () {  // 当点击确认按钮的时候会执行这个匿名函数
                    $.ajax({
                        url: '/delete_publisher/',
                        type: 'post',
                        data: {id: deleteId, csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()},
                        success: function (res) {
                            if (res.code === 0){
                                // 删除成功
                                // 在页面上删除当前行数据
                                var $currentTr = $('[pid=' + deleteId + ']');
                                // 更新序号
                                // 1. 先找到当前行后面所有的tr
                                var nextAllTr = $currentTr.nextAll('tr');
                                // 2. 每一个tr的第一个td 依次 -1
                                nextAllTr.each(function () {
                                    var num = $(this).children().eq(0).text()-1; // 这时候的this是进入循环的那个tr
                                    $(this).children().eq(0).text(num);
                                });
                                // 删掉当前行
                                $currentTr.remove();
                                // 弹框提示
                                swal('删除成功', '准备跑路吧!', 'success');
    
                            }else {
                                // 删除失败
                                swal('删除失败', res.err_msg, 'error');
                            }
                        }
                    })
                });
        })
    </script>
    </body>
    </html>
    View Code


    2.views.py
    
    # 首页
    def index(request):
        publisher_list = Publisher.objects.all()
        return render(request, 'index.html', {'publisher_list': publisher_list})
    
    
    # 删除出版社
    def delete_publisher(request):
        delete_id = request.POST.get('id')
        res = {'code': 0}
        try:
            Publisher.objects.filter(id=delete_id).delete()
        except Exception as e:
            res['code'] = 1
            res['err_msg'] = str(e)
        return JsonResponse(res)
    View Code
    
    
    
    
    三、Cookie
    1、介绍
    1.Cookie的由来
    大家都知道HTTP协议是无状态的。
    
    无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情况。
    
    一句有意思的话来描述就是人生只如初见,对服务器来说,每次的请求都是全新的。
    
    状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态的就以为这些数据不会被保留。会话中产生的数据又是我们需要保存的,也就是说要“保持状态”。因此Cookie就是在这样一个场景下诞生。
    
    
    2.什么是Cookie
      Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。
      简单点说,Cookie就是服务端给浏览器的小纸条!保存在浏览器端的键值对。
    
    
    3.Cookie的原理
      cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。
    
    
    2、Django中操作Cookie(cookie是基于响应对象进行操作的)
    1.设置Cookie
    rep = HttpResponse(...)
    rep = render(request, ...)
    
    rep.set_cookie(key,value, max_age=秒)
    rep.set_signed_cookie(key, value, max_age=秒, salt='加密盐',...)
    
    参数:
        key, 键
        value='', 值
        max_age=None, 超时时间(常用浏览器使用这个)
        expires=None, 超时时间(这个参数是针对IE浏览器的)
        path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问
        domain=None, Cookie生效的域名
        secure=False, https传输
        httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
    
    
    2.获取Cookie
    set_cookie取值:
        request.COOKIES  --> 是一个大字典
        request.COOKIES['key'] 或者 request.COOKIES.get('key', '设置取不到值时默认使用的值')
    
    set_signed_cookie取值:
        request.get_signed_cookie(key='', salt='set_signed_cookie的salt的值', default=获取不到值的时候默认使用的值, max_age=None)
    
    参数:
        default: 默认值
        salt: 加密盐
        max_age: 后台控制过期时间
    
    
    
    3.删除Cookie
    def logout(request):
        rep = redirect("/login/")
        rep.delete_cookie("user")  # 删除用户浏览器上之前设置的usercookie值
        return rep
    
    
    
    3、Cookie登录验证示例
    1.index页面代码就是上面的代码
    
    2.login页面代码
    
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta http-equiv="content-type" charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Login</title>
        {% load static %}
        <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}">
    </head>
    
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-4 col-md-offset-4" style="margin-top: 70px">
                <h2 class="text-center">欢迎登录</h2>
                <form action="" method="post">
                    {% csrf_token %}
                    <div class="form-group">
                        <label for="exampleInputUser">用户名</label>
                        <input type="text" class="form-control" id="exampleInputUser" placeholder="username" name="username">
                    </div>
                    <div class="form-group">
                        <label for="exampleInputPassword1">密码</label>
                        <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password" name="password">
                    </div>
                    <div class="checkbox">
                        <label>
                            <input type="checkbox" name="remember" value="seven"> 七天记住密码
                        </label>
                    </div>
                    <button type="submit" class="btn btn-success btn-block">登录</button>
                    <p style="color: red;">{{ error_msg }}</p>
                </form>
            </div>
        </div>
    </div>
    
    
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script>
    </body>
    </html>
    View Code

    3.views.py
    from django.shortcuts import render, HttpResponse, redirect
    from functools import wraps
    from django import views
    from app01.models import *
    from django.http import JsonResponse
    # Create your views here.
    
    
    # 用装饰器做cookie登录验证
    def check_login(func):
        @wraps(func)
        def inner(request, *args, **kwargs):
            # 先做cookie验证,如果cookie中有我登录的信息,则可以访问指定的页面
            if request.COOKIES.get('xm') == 'sb':
                rep = func(request, *args, **kwargs)
                return rep
            else:
                # 否则,让用户去登录
                # 拿到当前访问的url
                return_url = request.path_info
                return redirect('/login/?returnUrl={}'.format(return_url))
        return inner
    
    
    
    # 登录
    class LoginView(views.View):
        def get(self, request):
            return render(request, 'login.html')
    
        def post(self, request):
            username = request.POST.get('username')
            pwd = request.POST.get('password')
            is_rem = request.POST.get('remember', None)
            is_ok = UserInfo.objects.filter(name=username, password=pwd)
            if is_ok:
                # 判断是否从其他页面跳转到登录页面,拿到return_url
                # 如果取不到returnUrl,默认跳转到index页面
                return_url = request.GET.get('returnUrl', '/index/')
                rep = redirect(return_url)  # rep就是响应对象
                # 判断是否记住密码
                if is_rem:
                    # 是就保存七天
                    rep.set_cookie('xm', 'sb', max_age=60*60*24*7)
                else:
                    # 不是就不保存
                    rep.set_cookie('xm', 'sb')  # 告诉浏览器在自己本地保存一个键值对
                return rep
            else:
                return render(request, 'login.html', {'error_msg': '用户名或者密码错误'})
    
    
    # 首页
    @check_login
    def index(request):
        publisher_list = Publisher.objects.all()
        return render(request, 'index.html', {'publisher_list': publisher_list})
    
    
    # 删除出版社
    def delete_publisher(request):
        delete_id = request.POST.get('id')
        res = {'code': 0}
        try:
            Publisher.objects.filter(id=delete_id).delete()
        except Exception as e:
            res['code'] = 1
            res['err_msg'] = str(e)
        return JsonResponse(res)
    
    
    @check_login
    def home(request):
        return HttpResponse('home')
    
    
    # 注销
    def logout(request):
        rep = redirect('/login/')
        rep.delete_cookie('xm')
        return rep
    View Code
    
    
    
    
    
    四、Session
    1、介绍
    cookied的缺点:
        Cookie保存在浏览器端,不安全
        Cookie的长度不能超过4096字节
    
    Session:
        Session是用于保持状态的基于 Web服务器的方法。Session 允许通过将对象存储在 Web服务器的内存中在整个用户会话过程中保持任何对象。
        通俗来说,Session就是保存在服务器端的键值对,Session的键作为Cookie的值存在浏览器中,那么即使被截取了,也只是取到了Session的键,
        浏览器发送请求时,服务端就可以根据cookie的传过来的值,找到Session的键,从而去服务器的数据库(文件等)找到对应的值。
    
    注意:
        Cookie和Session其实是共通性的东西,不限于语言和框架。
    
    
    
    2、Session的原理
        用户名密码通过验证后:
        1.生成一个随机字符串(不同用户的随机字符串是不同的)
        2.在后端定义一个大字典,字典的key就是上面的随机字符串,值是你设置的值
        3.在服务器端的数据库(或者文件等)存储上面定义的字典(值存储的时候,session会自动帮我们加密)
        4.把随机字符串当成cookie的值给浏览器返回(浏览器收到的cookie默认键值对是: {"sessionid": 随机字符串})
        5.如果使用python的ORM,这个大字典会默认保存在django_session这张表中
     1、session设置值的过程
     request.session['name'] = 'xiaoming'
    # 随机生成一个字符串作为key,key对应的值又是一个字典,字典里面的内容才是你request.session设置的具体值
    
    # session数据
    d = {
        'qwerioiuytr45421224ew': {'name': 'xiaoming'}
    }
    
    # 过程
    import json
    # 1. 字典序列化成字符串 s1 = json.dumps({'name': 'xiaoming'})
    # 2. 加密算法加密一下,得到 10e1dasdasdadasfsgdvf2rji0d2dqdsa
    # 3. 存到数据库
    
    # 数据库
    # session_key                            session_data                                        expire_date
    # qwerioiuytr45421224ew     10e1dasdasdadasfsgdvf2rji0d2dqdsa                    
    
    # 然后把这个随机字符串qwerioiuytr45421224ew作为cookie的值发送给浏览器
    
    
    
    2、session取值的过程
    # request.session.get('name')
    
    # 1. 先从请求携带的Cookie数据中拿到随机字符串 :qwerioiuytr45421224ew
    # 2. 利用session_key去数据库查询,拿到session_data: 10e1dasdasdadasfsgdvf2rji0d2dqdsa
    # 3. 解密
    # 4. 反序列化 --> 得到一个保存当前这次请求的session数据的字典
    # 5. 字典.get('name')
    Session原理解析


    
    
    3、Django中Session相关方法
    常用:
    # 获取Session中数据
    request.session['k1']
    request.session.get('k1',None)
    
    # 设置Session的数据
    request.session['k1'] = 123
    request.session.setdefault('k1',123) # 存在则不设置
    
    # 删除指定的Session数据
    del request.session['k1']
    
    # 会话session的key
    request.session.session_key
    
    # 将所有Session失效日期小于当前日期的数据删除
    request.session.clear_expired()
    
    # 删除当前会话的所有Session数据
    request.session.delete()
      
    # 删除当前的会话数据并删除会话的Cookie。
    request.session.flush() 
        这用于确保前面的会话数据不可以再次被用户的浏览器访问
        例如,django.contrib.auth.logout() 函数中就会调用它。
    
    # 设置会话Session和Cookie的超时时间
    request.session.set_expiry(value)   
        * 如果value是个整数,session会在指定的秒数后失效。
        * 如果value是个datatime或timedelta,session就会在这个时间后失效。
        * 如果value是0,用户关闭浏览器session就会失效。
        * 如果value是None,session会依赖全局session失效策略。
    
    注意:
        失效不等于删除,失效是那个session和cookie不能使用了,但是数据库仍存着session的值,
        而删除则是从数据库中把session的值删除了
    
    
    不常用:
    # 获取所有的键、值、键值对
    request.session.keys()
    request.session.values()
    request.session.items()
    request.session.iterkeys()
    request.session.itervalues()
    request.session.iteritems()
    
    # 检查会话session的key在数据库中是否存在
    request.session.exists("session_key")
    
    
    
    4、Session版的登录验证
    
    from django.shortcuts import render, HttpResponse, redirect
    from functools import wraps
    from django import views
    from app01.models import *
    from django.http import JsonResponse
    # Create your views here.
    
    
    # 用装饰器做session登录验证
    def check_login(func):
        @wraps(func)
        def inner(request, *args, **kwargs):
            # session版
            # 验证
            session_user = request.session.get('user', None)
            if session_user:
                rep = func(request, *args, **kwargs)
                return rep
            else:
                # 否则,让用户去登录
                # 拿到当前访问的url
                return_url = request.path_info
                return redirect('/login/?returnUrl={}'.format(return_url))
        return inner
    
    
    # 登录
    class LoginView(views.View):
        def get(self, request):
            return render(request, 'login.html')
    
        def post(self, request):
            # session版
            username = request.POST.get('username')
            pwd = request.POST.get('password')
            is_rem = request.POST.get('remember', None)
            # 不推荐使用get,因为get取不到值会报错
            user_obj = UserInfo.objects.filter(name=username, password=pwd).first()
            if user_obj:
                return_url = request.GET.get('returnUrl', '/index/')
                request.session['user'] = user_obj.name
                # 判断是否记住密码
                if is_rem:
                    # 是就保存七天
                    request.session.set_expiry(60*60*24*7)
                else:
                    # 不是的话关闭浏览器就失效
                    request.session.set_expiry(0)
                return redirect(return_url)
            else:
                return render(request, 'login.html', {'error_msg': '用户名或者密码错误'})
    
    
    # 首页
    @check_login
    def index(request):
        publisher_list = Publisher.objects.all()
        return render(request, 'index.html', {'publisher_list': publisher_list})
    
    
    # 注销
    def logout(request):
        # request.session.delete()  # 删除session
        request.session.flush()  # 删除session并让cookie失效
        return redirect('/login/')
    View Code


    5、Django中的Session配置
    在setting.py里面设置的关于session的全局变量配置
    
    1. 数据库Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认把session存在数据库)
    
    2. 缓存Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎(把session存在缓存中)
    SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
    
    3. 文件Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎(把session存在文件中)
    SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 
    
    4. 缓存+数据库
    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎(把session存在数据库和缓存中)
    
    5. 加密Cookie Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎(把session存在浏览器中,相当于加盐的cookie)
    
    其他公用设置项:
    SESSION_COOKIE_NAME = "sessionid"          # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_AGE = 1209600                # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False     # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False          # 每次请求都刷新Session的有效期,默认修改之后才保存(默认)
    
    注意:
    SESSION_COOKIE_AGE设置的是全局的session失效日期,
    request.session.set_expiry(value)设置的是某个具体的请求的session失效日期(局部) 
    
    不常用:
    SESSION_COOKIE_PATH = "/"                  # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None                # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False               # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True              # 是否Session的cookie只支持http传输(默认)
    
    
    
    五、使用装饰器
    1、FBV中加装饰器
    首先定义一个装饰器
    然后直接在要被装饰的函数上一行添加装饰器
    
    例如:
    # 装饰器函数
    def check_login(func):
        @wraps(func)
        def inner(request, *args, **kwargs):
            # 先做cookie验证,如果cookie中有我登录的信息,则可以访问指定的页面
            if request.COOKIES.get('xm') == 'sb':
                rep = func(request, *args, **kwargs)
                return rep
            else:
                # 否则,让用户去登录
                # 拿到当前访问的url
                return_url = request.path_info
                return redirect('/login/?returnUrl={}'.format(return_url))
        return inner
    
    # 使用装饰
    @check_login
    def home(request):
        return HttpResponse('home')
    
    
    2、CBV中加装饰器相关
    # CBV示例
    class UserinfoView(views.View):
        def get(self, request):
            return HttpResponse('OK')
    
        def post(self, request):
            return redirect('/index/')
    
    先观察CBV的函数和装饰器函数,明显可以看到,装饰器函数的参数和CBV的函数的参数不一致,
    CBV的参数中多了一个self,那么传到装饰器中使用的时候,装饰器中inner的参数request就代表CBV中函数的self,
    后续CBV的request就会被装饰器的*args接收,此时是没有问题的,但是,在装饰器使用request的时候就出问题了,
    因为装饰器中inner的参数request就代表CBV中函数的self,而self明显就没有request的那些方法,所以就会报错。
    
    Django提供了解决这一问题的方法:
    1.方法一
    # 直接加在CBV视图的get或post方法上
    from django.utils.decorators import method_decorator
    
    class UserinfoView(views.View):
        @method_decorator(check_login)
        def get(self, request):
            return HttpResponse('OK')
    
        def post(self, request):
            return redirect('/index/')
    
    2.方法二
    # 加在dispatch方法上
    from django.utils.decorators import method_decorator
    
    class UserinfoView(views.View):
    
        @method_decorator(check_login)
        def dispatch(self, request, *args, **kwargs):
            return super(UserinfoView, self).dispatch(request, *args, **kwargs)
    
        def get(self, request):
            return HttpResponse('OK')
    
        def post(self, request):
            return redirect('/index/')
    
    因为CBV中首先执行的就是dispatch方法,所以这么写相当于给get和post方法都加上了登录校验
    
    
    3.方法三
    直接加在视图类上,但method_decorator必须传 name 关键字参数
    
    # 如果get方法和post方法都需要登录校验的话就写两个装饰器。
    from django.utils.decorators import method_decorator
    
    @method_decorator(check_login, name="get")
    @method_decorator(check_login, name="post")
    class UserinfoView(views.View):
    
        def dispatch(self, request, *args, **kwargs):
            return super(UserinfoView, self).dispatch(request, *args, **kwargs)
    
        def get(self, request):
            return HttpResponse('OK')
    
        def post(self, request):
            return redirect('/index/')
    
    
    六、补充
    1、CSRF Token相关装饰器在CBV只能加到dispatch方法上,或者加在视图类上然后name参数指定为dispatch方法。
    如果是FBV则直接添加 @csrf_exempt 即可
    
    注意:
        csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
        csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
    
    2、示例
    from django.views.decorators.csrf import csrf_exempt, csrf_protect
    from django.utils.decorators import method_decorator
    
    
    class UserinfoView(views.View):
    
        @method_decorator(csrf_exempt)
        def dispatch(self, request, *args, **kwargs):
            return super(UserinfoView, self).dispatch(request, *args, **kwargs)
    
        def get(self, request):
            return HttpResponse('OK')
    
        def post(self, request):
            return redirect('/index/')
    
    或者
    
    @method_decorator(csrf_exempt, name='dispatch')
    class UserinfoView(views.View):
    
        def dispatch(self, request, *args, **kwargs):
            return super(UserinfoView, self).dispatch(request, *args, **kwargs)
    
        def get(self, request):
            return HttpResponse('OK')
    
        def post(self, request):
            return redirect('/index/')
    复制代码
  • 相关阅读:
    K8S 内部服务调用域名解析超时
    云原生服务网格istio 第二章
    云原生服务网格istio 第一章
    kubernetes权威指南 第4版 第十章节读书笔记
    Navicat Premium基本使用
    Mac安装SecureCRT
    zabbix监控ssl证书到期时间
    nginx 配置proxy_pass URL末尾加与不加/(斜线)的区别
    PyCharm 项目删除
    Pycharm问题:module 'pip' has no attribute 'main'
  • 原文地址:https://www.cnblogs.com/yidashi110/p/10091957.html
Copyright © 2011-2022 走看看