• Django 中 cookie的使用


    Cookie是浏览器在客户端留下的一段记录,这段记录可以保留在内存或者硬盘上。因为Http请求是无状态的,通过读取cookie的记录,服务器或者客户端可以维持会话中的状态。比如一个常见的应用场景就是登录状态。Django里面,对cookie的读取和设置很简单。Cookie本身的格式类似字典,因此可以通过request的key或者get获取;然后他的设置则是通过response对象的set_cookie设定; 如果要取消cookie,把过期时间设置为当前时间就行了。

    获取Cookie:

    1
    2
    3
    4
    5
    6
    request.COOKIES['key']
    request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
        参数:
            default: 默认值
            salt: 加密盐
            max_age: 后台控制过期时间

    设置Cookie:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    rep = HttpResponse(...) 或 rep = render(request, ...)
      
    rep.set_cookie(key,value,...)
    rep.set_signed_cookie(key,value,salt='加密盐',...)
        参数:
            key,              键
            value='',         值
            max_age=None,     超时时间
            expires=None,     超时时间(IE requires expires, so set it if hasn't been already.)
            path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
            domain=None,      Cookie生效的域名
            secure=False,     https传输
            httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

    例1  设置一个login登录界面,一个index登录成功之后的跳转界面,如果没有登录那么自动跳转到登录界面

    views.py 

    1
    2
    3
    4
    5
    6
    def index(reqeust):
        # 获取当前已经登录的用户
        = reqeust.COOKIES.get('username111')
        if not v:
            return redirect('/login/')
        return render(reqeust,'index.html',{'current_user': v})

    注意Cookie的超时时间有2种方式,一个是直接指定max_age(N秒后超时),一个是指定expires后面跟一个具体的时间对象

    httponly可以禁止JavaScript获取这个值,但是实际上没有什么鸟用,chrome或者抓包都能轻松获取所有的cookie

    index.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1>欢迎登录:{{ current_user }}</h1>
    </body>
    </html>

    login.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form action="/login/" method="POST">
            <input type="text" name="username" placeholder="用户名" />
            <input type="password" name="pwd" placeholder="密码" />
            <input type="submit" />
        </form>
    </body>
    </html>

    例2:

    现实生活中,一般是把这个验证cookie的功能写成装饰器,这样直接在其他函数上面调用就行了板面

    把例1改一下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def auth(func):
        def inner(reqeust,*args,**kwargs):
            = reqeust.COOKIES.get('username111')
            if not v:
                return redirect('/login/')
            return func(reqeust, *args,**kwargs)
        return inner
         
    @auth
    def index(reqeust):
        # 获取当前已经登录的用户
        = reqeust.COOKIES.get('username111')
        return render(reqeust,'index.html',{'current_user': v})

    例3: 我们知道可以使用fbv或者cbv来路由函数。例2使用了fbv的方式,用cbv也能实现

    cbv里面,如果只打算装饰一个方法,那么直接在方法前面加个@method_decorator就行;如果打算装饰这个类里面所有的方法,那么在整个类的最上面进行装饰

    views.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @method_decorator(auth,name='dispatch')
    class Order(views.View):
        # @method_decorator(auth)
        # def dispatch(self, request, *args, **kwargs):
        #     return super(Order,self).dispatch(request, *args, **kwargs)
        # @method_decorator(auth)
        def get(self,reqeust):
            = reqeust.COOKIES.get('username111')
            return render(reqeust,'index.html',{'current_user': v})
        def post(self,reqeust):
            = reqeust.COOKIES.get('username111')
            return render(reqeust,'index.html',{'current_user': v})

    urls.py

    1
      url(r'^order/', views.Order.as_view()),

    例4 我们还可以通过JavaScript或者JQuery来设置Cookie,比如在前面分页的代码基础上,我们增加一个自定义显示行数的功能。

    user_list.html  这里下了一个JQuery的插件,这样读取设置cookie比较容易;而且,我们还限制了cookie的使用范围,不是默认的所有范围,而是仅仅局限于/user_list这个路径里面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .go{
                20px;
                 border: solid 1px;
                color: #66512c;
                display: inline-block;
                padding: 5px;
            }
            .pagination .page{
                border: solid 1px;
                color: #66512c;
                display: inline-block;
                padding: 5px;
                papayawhip;
                margin: 5px;
            }
            .pagination .page.active{
                brown;
                color: white;
            }
        </style>
    </head>
    <body>
        <ul>
            {% for item in li %}
                {% include 'li.html' %}
            {% endfor %}
        </ul>
        <div>
            <select id="ps" onchange="changePageSize(this)">
                <option value="10">10</option>
                <option value="30">30</option>
                <option value="50">50</option>
                <option value="100">100</option>
            </select>
        </div>
        <div class="pagination">
            {{ page_str }}
        </div>
        <script src="/static/jquery-1.12.4.js"></script>
        <script src="/static/jquery.cookie.js"></script>
        <script>
            $(function(){
                    var v = $.cookie('per_page_count', {'path': "/user_list/`"});
                    console.log(v)
                    $('#ps').val(v);
            });
            function changePageSize(ths){
                var v = $(ths).val();
                console.log(v);
                $.cookie('per_page_count',v, {'path': "/user_list/"});          
                location.reload();
            }
        </script>
    </body>
    </html>

    views.py  从前端获取每页行数,实例化的时候传递给我们的分页类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    def user_list(request):
        current_page = request.GET.get('p'1)
        current_page = int(current_page)
        val = request.COOKIES.get('per_page_count',10)
        val = int(val)
        page_obj = pagination.Page(current_page,len(LIST),val)
     
        data = LIST[page_obj.start:page_obj.end]
        page_str = page_obj.page_str("/user_list/")
        return render(request, 'user_list.html', {'li': data,'page_str': page_str})

    wKioL1mU4aLzyQZgAAB9Fjf60mE310.jpg

  • 相关阅读:
    ASP.NET Web API 中 特性路由(Attribute Routing) 的重名问题
    在 ASP.NET Web API 中,使用 命名空间(namespace) 来作为路由的参数
    【转】使用create_project.py创建cocos2d项目时出错
    WCF使用net.tcp绑定时的注意事项
    WCF:如何将net.tcp协议寄宿到IIS
    关于WCF服务的调试跟踪
    Windows Store Apps 开发转载
    如何让弹出窗口和页面产生联动?
    关于C# wpf DataGrid单元格双击设置单元格内容
    在WPF的DataGrid中对行添加单击事件
  • 原文地址:https://www.cnblogs.com/xxr1/p/7384603.html
Copyright © 2020-2023  润新知