• django修身大法之九阳真经


    cookie和session

    HTTP被设计为”无态”,也就是俗称“脸盲”。 这⼀次请求和下⼀次请求 之间没有任
    何状态保持,我们无法根据请求的任何方面(IP地址,用户代理等)来识别来自同⼀
    ⼈的连续请求。实现状态保持的方式:在客户端或服务器端存储与会话有关的数据
    (客户端与服务器端的⼀次通信,就是⼀次会话)

    • cookie
    • session

    不同的请求者之间不会共享这些数据,cookie和session与请求者⼀⼀对应。

    ⼀、cookie

    cookies 是浏览器为 Web 服务器存的⼀小信息。 每次浏览器从某个服务器请求页面时,都会自动带上以前收到的cookie。cookie保存在客户端,安全性较差,注意不要保存敏感信息。典型应用:

    • 网站登录
    • 购物车

    用法:

    # 1.设置cookie
    HttpResponse.set_cookie(key, value='', max_age=None, expires=None,
    path='/', domain=None, secure=None, httponly=False)
    参数:
     
        key: cookie的名称(*)
    
        value: cookie的值,默认是空字符
    
        max_age:cookies的持续有效时间(以秒计),如果设置为 None,cookies 在
        浏览器关闭的时候就失效了。
    
        expires:cookies的过期时间,格式:"Wdy, DD-Mth-YY HH:MM:SS GMT" 如果
        设置这个参数,它将覆盖max_age。
    
        path: cookie⽣效的路径前缀,浏览器只会把cookie回传给带有该路径的⻚
        ⾯,这样你可以避免将cookie传给站点中的其他的应⽤。/ 表示根路径,特殊的:根路径的cookie可以被任何url的⻚⾯访问
         domain: cookie⽣效的站点。你可⽤这个参数来构造⼀个跨站cookie。如,domain=".example.com" 所构造的
         cookie对下⾯这些站点都是可 读的: www.example.com 、
        www2.example.com。
    		如果该参数设置为None,cookie只能由设置它的站点读取。
         secure: 如果设置为 True ,浏览器将通过HTTPS来回传cookie。
         httponly: 仅http传输不能使⽤js获取cookie
    #同set_cookie,不同点在于设置salt,即加盐,加密存储cookie数据
    HttpResponse.set_signed_cookie(key, value, salt='', max_age=None,
    expires=None, path='/', domain=None, secure=None, httponly=False)
    
    #2 获取cookie
    HttpRequest.COOKIES.get(key)
    #获取加“盐”的cookie
    HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='',
    max_age=None)
    
    # 3删除cookie
    HttpResponse.delete_cookie(key, path='/', domain=None)
    

    ⼆、session

    cookie看似解决了HTTP(短连接、无状态)的会话保持问题,但把全部用户数据
    保存在客户端,存在安全隐患,

    于是session出现了。我们可以 把关于用户的数据保存在服务端,在客户端cookie
    里加⼀个sessionID(随机字符串)。其工作流程

    (1)、当用户来访问服务端时,服务端会生成⼀个随机字符串;

    (2)、当用户登录成功后 把 {sessionID :随机字符串} 组织成键值对加到cookie里发
    送给用户;

    (3)、服务器以发送给客户端 cookie中的随机字符串做键,用户信息做值,保存用户信息;

    (4)、再访问服务时客户端会带上sessionid,服务器根据sessionid来确认用户是否
    访问过网站

    2.1 cookie和session的区别与联系

    • 区别
      • session将数据存储与服务器端 cookie存储在客户端
      • cookie 存储在客户端,不安全,sess存储在服务器端,客户端只存
        sesseionid,安全
      • cookie在客户端存储值有大小的限制,大约几kb。session没有限制
    • 联系
      • session 基于cookie

    2.2 session配置

    1. 首先在settings.py中有如下配置(系统默认),
    INSTALLED_APPS = [
     'django.contrib.sessions',
    ]
    MIDDLEWARE = [
     'django.contrib.sessions.middleware.SessionMiddleware',
    ]
    
    1. 进行数据迁移,生成session使用的数据库表

    2.3 session操作

    • session设置
    def doregister(request):
         username = request.POST.get('username')
         password = request.POST.get('password')
         email = request.POST.get('email')
         user = User()
         user.username = username
         user.password = md5(password.encode('utf8')).hexdigest()
         user.email = email
         user.save()
         # 设置session
         request.session['username'] = username
         return render(request,"common/notice.html",context={
         'code':1,
         'msg':'注册成功',
         'url':'three:index',
         'wait':3
         })
    
    • session获取
    def index(request):
         # session获取
         username = request.session.get('username')
         return render(request,'three/index.html',context=
        {'username':username})
    
    • session删除
      • clear() 清空所有session 但是不会将session表中的数据删除
      • flush() 清空所有 并删除表中的数据
      • logout() 退出登录 清除所有 并删除表中的数据
      • del req.session['key'] 删除某⼀个session的值
    def logout(request):
         request.session.flush()
         return redirect(reverse("three:index"))
    
    • session过期时间

      req.session.set_expiry(5)

    分页

    1. Paginator 分页器

    Paginator用于分页,但Paginator并不具体管理具体的页的处理,而是使用Page
    对象管理具体页面

    • 创建分页器对象

    格式: Paginator(<query_set查询集>,每页显示数据的条数)

    • 对象的属性
      • count 分页对象的个数
      • num_pages 总页数
      • page_range 页码的列表
    • 方法
      • page(num) 返回page对象 如果给定的页码不存在 则抛出异常

    2. page 对象

    page对象具体负责每页的处理,包括每页的数据,当前页的页码,是否有上⼀页
    或下⼀页等.

    类别 名称 说明
    属性 object_list 当前页码上的所有数据
    属性 number 当前页码值
    属性 paginator 返回Paginator的对象
    方法 has_next 是否有下⼀页
    方法 has_previous 是否有上⼀页
    方法 has_other_pages 是否有上⼀页 或者下⼀页
    方法 next_page_number 返回下⼀页的页码
    方法 previous_page_number 返回上⼀页的页码
    方法 len 返回当前页数据的个数
    • 实例
    #路由
    url(r'^userlist/$',views.userlist,name='userlist'),
    url(r'^userlist/(d+)/$',views.userlist,name='userlist1'),
    
    # views.py
    def userlist(request,page=1):
         users = User.objects.all()
         # 实例化分⻚对象,⼀⻚两条记录
         pagination = Paginator(users,2)
         page = pagination.page(page) #某⼀⻚的分⻚对象
         return render(request,'userlist.html',context={
         'data':page.object_list, #当前⻚的数据(列表)
         'page_range':pagination.page_range,#⻚码范围
         'page':page
         })
    
    #模板⽂件
    {% load static %}
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial�scale=1">
        <!-- 上述3个meta标签*必须*放在最前⾯,任何其他内容都*必须*跟随其后! -
       ->
        <title>⽤户列表</title>
        <!-- Bootstrap -->
        <link href="{% static 'bootstrap/css/bootstrap.min.css' %}"
              rel="stylesheet">
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <div class="bs-example" data-example-id="bordered-table">
                <table class="table table-bordered">
                    <thead>
                    <tr>
                        <th>#</th>
                        <th>⽤户名</th>
                        <th>密码</th>
                        <th>年龄</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for user in data %}
                        <tr>
                            <th scope="row">{{ forloop.counter }}
                            </th>
                            <td>{{ user.username }}</td>
                            <td>{{ user.password }}</td>
                            <td>{{ user.age }}</td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-4"></div>
            <div class="col-md-5">
                <nav aria-label="Page navigation">
                    <ul class="pagination">
                        {% if page.has_previous %}
                            <li>
                                <a href="{% url 'app:userlist1'
    page.number|add:'-1' %}" aria-label="Previous">
     <span aria-hidden="true">&laquo;
    </span>
                                </a>
                            </li>
                        {% else %}
                            <li class="disabled">
     <span href="{% url 'app:userlist1'
    page.number|add:'-1' %}" aria-label="Previous">
     <span aria-hidden="true">&laquo;
    </span>
     </span>
                            </li>
                        {% endif %}
                        {% for num in pagerange %}
                            {% ifequal num page.number %}
                                <li class="active"><a href="{% url
    'app:userlist1' num %}">{{ num }}</a></li>
                            {% else %}
                                <li><a href="{% url 'app:userlist1'
    num %}">{{ num }}</a></li>
                            {% endifequal %}
                        {% endfor %}
                        {% if page.has_next %}
                            <li>
                                <a href="{% url 'app:userlist1'
    page.number|add:'1' %}" aria-label="Next">
     <span aria-hidden="true">&raquo;
    </span>
                                </a>
                            </li>
                        {% else %}
                            <li class="disabled">
     <span href="#" aria-label="Next">
     <span aria-hidden="true">&raquo;
    </span>
     </span>
                            </li>
                        {% endif %}
                    </ul>
                </nav>
            </div>
            <div class="col-md-3"></div>
        </div>
    </div>
    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必
    须放在前边) -->
    <script src="{% static 'bootstrap/js/jquery-1.12.4.min.js' %}">
    </script>
    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单
    个插件。 -->
    <script src="{% static 'bootstrap/js/bootstrap.min.js' %}">
    </script>
    </body>
    </html>
    
  • 相关阅读:
    [三]JavaIO之IO体系类整体设计思路 流的概念以及四大基础分类
    [二] JavaIO之File详解 以及FileSystem WinNTFileSystem简介
    [一]FileDescriptor文件描述符 标准输入输出错误 文件描述符
    [零] JavaIO入门简介 程序设计语言 为什么需要IO库
    装饰器模式 Decorator 结构型 设计模式 (十)
    适配器模式 adapter 结构型 设计模式(九)
    layui 鼠标悬停单元格显示全部
    mysql 日期总结
    区域块路由与全局路由兼容,双重路由
    JS-SDK相关参考
  • 原文地址:https://www.cnblogs.com/williamweson/p/13610966.html
Copyright © 2020-2023  润新知