zoukankan      html  css  js  c++  java
  • 第八篇:forms组件,cookie和session

    forms组件

    常常用于注册页面的用户输入的数据进行校验

    • 渲染页面
    • 校验数据
    • 展示信息

    在使用forms组件的时候,需要在应用下新建一个py文件,例如:
    myforms.py

    在文件中写一个类:

    from django import forms
     
     
    class MyRegForm(forms.Form):
        # 用户名最少3位最多8位
        username = forms.CharField(max_length=8,min_length=3)
        password = forms.CharField(max_length=8,min_length=3)
        # email字段必须填写符合邮箱格式的数据
        email = forms.EmailField()
    

    forms校验数据

    数据校验语法:

    • .is_valid() 校验是否符合规则
    • .cleaned_data 获取通过校验的数据
    • .errors 获取校验失败以及校验失败的原因,返回的是一个li套ul的,前端展示会打乱布局
    # 1.传入待校验的数据  用自己写的类 传入字典格式的待校验的数据
    form_obj = views.MyRegForm({'username':'jason','password':'12','email':'123456'})
    # 2.判断数据是否符合校验规则
    form_obj.is_valid()  # 该方法只有在所有的数据全部符合校验规则才会返回True
    False
    # 3.如何获取校验之后通过的数据
    form_obj.cleaned_data
    {'username': 'jason'}
    # 4.如何获取校验失败及失败的原因
    form_obj.errors
    {
    'password': ['Ensure this value has at least 3 characters (it has 2).'],
    'email': ['Enter a valid email address.']
    }
    # 5.注意 forms组件默认所有的字段都必须传值 也就意味着传少了是肯定不行的 而传多了则没有任何关系 只校验类里面写的字段 多传的直接忽略了
    form_obj = views.MyRegForm({'username':'jason','password':'123456'})
    form_obj.is_valid()
    Out[12]: False
    form_obj.errors
    Out[18]: {'email': ['This field is required.']}
     
    # 多传的hobby字段,在MyRegForm类中并没有限制,因此,这里的hobby会被忽略,只校验类中的字段
    form_obj = views.MyRegForm({'username':'jason','password':'123456',"email":'123@qq.com',"hobby":'hahahaha'})
    form_obj.is_valid()
    Out[14]: True
    form_obj.cleaned_data
    Out[15]: {'username': 'jason', 'password': '123456', 'email': '123@qq.com'}
    form_obj.errors
    Out[16]: {}
    

    forms渲染标签

    forms组件只帮忙渲染获取用户输入、选择、下拉、文件的标签,不渲染按钮和form表单的标签

    渲染出来的每一个input提示信息都是类中字段,首字母大写(除非在类中的字段括号内利用label定义提示信息)

    1、先写一个类

    from django import forms
     
     
    class MyRegForm(forms.Form):
        # 用户名最少3位最多8位
        username = forms.CharField(max_length=8,min_length=3)
        password = forms.CharField(max_length=8,min_length=3)
        # email字段必须填写符合邮箱格式的数据
        email = forms.EmailField()
    

    2、urls.py

    url(r'^reg/', views.reg)
    

    3、views.py

    def teg(request):
        # 1、先生成一个空的对象
        form_obj = MyRegForm()
        # 2、直接将该对象传给前端页面
        return render(request, 'reg.html',  locals())
    

    4、在reg.html页面中进行测试

    第一种渲染方式:多个p标签 本地测试方便 封装程度太高了 不便于扩展

    # reg.html
     
    {{ form_obj.as_p }}
    

    # reg.html
    {{ form_obj.as_ul }}
    

    # reg.html
    {{ form_obj.as_table }}
    

    第二种渲染方式:扩展性较高,书写较为繁琐

    {{ form_obj.username.id_for_label }}  # 获取字段的id
    {{ form_obj.username.label }}  # 获取的是字段的提示信息User
    {{ form_obj.username }}  # 为类中的username产生一个input框
     
    # reg.html
    <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>{{ form_obj.username }}
    {{ form_obj.password.label }}{{ form_obj.password }}
    {{ form_obj.email.label }}{{ form_obj.email }}
    

    第三种渲染方式,推荐使用:

    不管class类中定义多个字段,for循环下,所有的字段都可以渲染出来

    # reg.html
     
    {% for form in form_obj %}
    <p>{{ form.label }}{{ form }}</p>
    {% endfor %}
    

    forms渲染错误信息(提示信息)

    1、前端自动校验

    前端代码:

    # reg.html
     
    <form action="" method="post">
        {% for form in form_obj %}
        <p>{{ form.label }}{{ form }}</p>
        {% endfor %}
        <input type="submit">
    </form>
    

    后端代码:

    # views.py
     
    def reg(request):
        # 1、先生成一个空的对象
        form_obj = MyRegForm()
        if request.method == 'POST':
            # 3、获取用户输入的所有数据并交给forms组件校验
            form_obj = MyRegForm(request.POST)  # 对上面的空对象重新赋值
            # 4、获取校验结果
            if form_obj.is_valid():
                return HttpResponse('数据没有问题!')
            else:
                # 5.后端打印失败字段和提示信息
                print(form_obj.errors)
     
        # 2、直接将该对象传给前端页面
        return render(request, 'reg.html', locals())
    

    数据校验必须前后端都有,但是前端校验弱不禁风,可有可无,而后端的校验则必须要非常全面

    因此们可以取消浏览器自动帮我们校验的功能:

    # form表单取消前端浏览器自动校验功能
     
    <form action="" method="post" novalidate>  # 在form标签内设置novalidate
    

    前端代码:

    <form action="" method="post" novalidate>
        {% for form in form_obj %}
        <p>
            {{ form.label }}{{ form }}
        <sanp>{{ form.errors.0 }}</sanp>
        </p>
        {% endfor %}
        <input type="submit">
    </form>
    

    前端代码form.errors如果不索引0,那么取出的是一个ul套li的形式,会打乱页面布局:

    def reg(request):
        # 1、先生成一个空的对象
        form_obj = MyRegForm()  # 第一次get请求传入空字典,只是为了渲染页面
        if request.method == 'POST':
            # 3、获取用户输入的所有数据并交给forms组件校验
            form_obj = MyRegForm(request.POST)  # 对上面的空对象重新赋值,此时post请求,是为了校验
            # 4、获取校验结果
            if form_obj.is_valid():
                return HttpResponse('数据没有问题!')
            else:
                # 5.后端打印失败字段和提示信息
                print(form_obj.errors)
     
        # 2、直接将该对象传给前端页面
        return render(request, 'reg.html', locals())
    

    效果如下:

    但我们发现,上面的效果并不是很好,提示信息为英文,报错信息也没办法自定义,input框中输入密码也是明文,因此我们需要更近一步的完善,为此我们需要forms组件中的常用参数。

    forms组件中常用参数

    • label input框的提示信息
    • error_messages 自定义报错的提示信息
    • required 设置字段是否允许为空
    • initial 设置默认值
    • widget 控制type类型及属性(调整input框的样式)

    label设置input框的提示信息:

    # 在定义的类中的字段括号内添加参数
    username = forms.CharField(max_length=8, min_length=3, label='用户名:')
    

    效果如下:

    error_messages自定义报错信息:

    class MyRegForm(forms.Form):
        # 用户名最少3位最多8位
        username = forms.CharField(
            max_length=8, min_length=3, label='用户名:',
            error_messages={
                'max_length': '用户名最长8个字符!',
                'min_length': '用户名最短3个字符!',
                'required': '用户名不能为空!',
            }
                                   )
     
        # 设置邮箱校验
        # email字段必须填写符合邮箱格式的数据
        email = forms.EmailField(label='邮箱',error_messages={
            'required':'邮箱必填',
            'invalid':'邮箱格式不正确'
        })
    

    字段默认必填,可以通过required设置字段为空:

    class MyRegForm(forms.Form):
        # 用户名最少3位最多8位
        username = forms.CharField(
            max_length=8, min_length=3, label='用户名:',
            error_messages={
                'max_length': '用户名最长8个字符!',
                'min_length': '用户名最短3个字符!'
            },
            required=False
                                   )
    

    initial设置为默认值:

    class MyRegForm(forms.Form):
        # 用户名最少3位最多8位
        username = forms.CharField(
            max_length=8, min_length=3, label='用户名:',
            error_messages={
                'max_length': '用户名最长8个字符!',
                'min_length': '用户名最短3个字符!'
            },
            required=False, initial='我是默认值'
                                   )
    

    widget控制type类型及属性(调整input框的样式)

    # 设置widget=forms.widgets.passwordInput(),使密码变为密文显示
    # attr设置input框的样式
     
    password = forms.CharField(max_length=8,min_length=3,label='密码',
                               widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})
                               )
    
    widget=forms.widgets.TextInput(attrs={'class':'form-control c1 c2'})
    

    全局或局部钩子

    使用全局或者局部钩子,其实相当于第二层的校验,多了一层校验

    全局钩子:针对多个字段,一般用于第二次确认密码是否一致

    局部钩子:针对单个字段,校验用户名中不能包含666

    # 定义类
     
    class MyRegForm(forms.Form):
        # 用户名最少3位最多8位
        username = forms.CharField(max_length=8, min_length=3, label='用户名:')
        password = forms.CharField(max_length=8, min_length=3, label='密码:')
        confirm_password = forms.CharField(max_length=8, min_length=3, label='密码:')
    
    # 全局钩子
     
    def clean(self):
        # 校验密码和确认密码是否一致
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if not password == confirm_password:
            # 展示提示信息
            self.add_error('confirm_password','两次密码不一致')
        return self.cleaned_data
     
    # 局部钩子
    def clean_username(self):
        username = self.cleaned_data.get('username')
        if '666' in username:
            self.add_error('username','光喊666是不行的')
        return username
     
    # 如果你想同时操作多个字段的数据你就用全局钩子
    # 如果你想操作单个字段的数据 你就用局部钩子
    

    forms补充知识点

    正则校验

    • RegexValidator
    phone = forms.CharField(
        validators=[
            RegexValidator(r'^[0-9]+$', '请输入数字'),
            RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
        ]
    )
    

    利用forms组件校验注册功能

    首先在应用下新建一个myforms.py文件

    # myforms.py
    
    from django import forms
    from app01 import models
    
    class MyRegForm(forms.Form):
        username = forms.CharField(
            min_length=3, max_length=8, label='用户名:',
      error_messages={
                'min_length': '用户名最短3个字符!',
      'max_length': '用户名最长8个字符!',
      'required': '用户名不能为空!'
      },
      widget=forms.widgets.TextInput(attrs={'class': 'form-control'})
        )
        password = forms.CharField(
            min_length=3, max_length=8, label='密码:',
      error_messages={
                'min_length': '密码最短3个字符!',
      'max_length': '密码最长8个字符!',
      'required': '密码不能为空!'
      },
      widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'})
        )
        confirm_password = forms.CharField(
            min_length=3, max_length=8, label='确认密码:',
      error_messages={
                'min_length': '确认密码最短3个字符!',
      'max_length': '确认密码最长8个字符!',
      'required': '确认密码不能为空!'
      },
      widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'})
        )
        email = forms.EmailField(
            label='邮箱',
      error_messages={
                'required': '邮箱不能为空',
      'invalid': '邮箱格式不正确'
      },
      widget=forms.widgets.TextInput(attrs={'class': 'form-control'})
        )
    
        # 钩子函数
      # 局部钩子校验用户名是否已存在
      def clean_username(self):
            username = self.cleaned_data.get('username')
            is_alive = models.UserInfo.objects.filter(username=username)
            if is_alive:
                self.add_error('username', '用户名已存在!')
            return username
    
        # 全局钩子校验密码与确认密码是否一致
      def clean(self):
            password = self.cleaned_data.get('password')
            confirm_password = self.cleaned_data.get('confirm_password')
            if password != confirm_password:
                self.add_error('confirm_password', '两次密码不一致!')
            return self.cleaned_data
    

    在views.py中书写逻辑代码:

    # views.py
    
    from app01.myforms import MyRegForm
    
    def register(request):
        # 1、先生成form_obj对象
      form_obj = MyRegForm()
        # if request.is_ajax():  # 判断当前请求是否是ajax
      if request.method == 'POST':
            # 定义一个与ajax回调函数交互的字典
      back_dic = {'code': 1000, 'msg': ''}
    
            # 校验数据 用户名 密码和确认密码
      form_obj = MyRegForm(request.POST)
            if form_obj.is_valid():
                clean_data = form_obj.cleaned_data  # 用变量接收正确的结果,clean_data = {'username', 'password', 'confirm_password', 'email'}
     # 将确认密码的键值对删除
      clean_data.pop('confirm_password')
                # 获取用户头像文件
      avatar_obj = request.FILES.get('avatar')
                # 判断用户头像是否为空
      if avatar_obj:
                    # 添加到clean_data中
      clean_data['avatar'] = avatar_obj  # clean_data = {'username', 'password', 'avatar_obj', 'email'}
      models.UserInfo.objects.create_user(**clean_data)
                    back_dic['msg'] = '注册成功!'
      back_dic['url'] = '/login/'
      else:
                back_dic['code'] = 2000
      back_dic['msg'] = form_obj.errors
            return JsonResponse(back_dic)
    
        # 2、将form_obj对象返回给html页面
      return render(request, 'register.html', locals())
    
    

    html页面

    # register.py
    
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>注册页面</title>
     <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
      {% load static %}
        <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
     <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
     <div class="row">
     <h2 class="text-center">注册页面</h2>
     <div class="col-md-8 col-md-offset-2">
     <form id="myform">
      {% csrf_token %}
    
                    {% for form in form_obj %}
                        <div class="form-group">
     <label for="{{ form.id_for_label }}">{{ form.label }}</label>
      {{ form }}
                        <span style="color: red" class="pull-right"></span>
     </div>  {% endfor %}
    
                    <div class="form-group">
     <label for="id_avatar">用户头像:<img src="/static/image/default.jpg" alt="" width="80" style="margin-left: 10px" id="id_img"></label>
     <input type="file" name="myfile" id="id_avatar" style="display: none">
     </div>
     <input type="button" value="取消" class="btn btn-default btn-sm">
     <input type="button" value="注册" class="btn btn-primary btn-sm pull-right" id="id_submit">
                 </form>
    
     </div> </div></div>
    <script>
      $('#id_avatar').change(function () {
            // 1、先获取用户上传的头像文件
      var avatarFile = $(this)[0].files[0];
      // 2、利用文件阅读器对象
      var myFileReader = new FileReader();
      // 3、将文件交由阅读器对象读取
      myFileReader.readAsDataURL(avatarFile);
      // 4、修改img标签的src属性,等待文件阅读器对象读取文件之后再操作img标签
      myFileReader.onload = function(){
                $('#id_img').attr('src', myFileReader.result)
            }
        });
    
      // 点击按钮触发ajax提交动作
      $('#id_submit').on('click', function () {
            // 1、先生成一个内置对象 FormData  var myFormData = new FormData();
      // 2、添加普通键值对
      {#console.log($('#myform').serializeArray())#}
      $.each($('#myform').serializeArray(), function (index, obj) {
                myFormData.append(obj.name, obj.value)
            });
      // 3、添加文件数据
      myFormData.append('avatar', $('#id_avatar')[0].files[0])
            // 4、发送数据
      $.ajax({
                url: '',
      type: 'post',
      data: myFormData,
      // 两个关键性参数
      contentType: false,
      processData: false,
    
      success: function (data) {
                    if (data.code===1000){
                        // 注册成功之后 应该跳转到后端返回过来的url
      location.href = data.url
      }else{
                        $.each(data.msg, function (index, obj) {
                            // 1、先手动拼接字段名所对应的input框的id值
      var targetId = '#id_' + index; // id_username
     // 2、利用id选择器查找标签
      $(targetId).next().text(obj[0]).parent().addClass('has-error')
                        })
                    }
                }
            })
        });
      $('input').focus(function () {
            // 移除span标签内部的文本 还需要移除div标签的class中的has-error属性
      $(this).next().text('').parent().removeClass('has-error')
        })
    </script>
    </body>
    </html>
    

    django的cookie和session

    cookie:保存在服务端的键值对

    session:保存在服务端上的键值对

    cookie与session的作用:

    • 解决http协议的无状态特征
    • 保存信息

    cookie产生

    当用户第一次登陆成功之后,服务端会返回一个随机字符串,保存在客户端浏览器上,之后再次超服务端发送请求,只需要携带该随机字符串,服务端就能够识别当前用户身份。

    cookie可以设置超时时间,超过一定的时间,cookie就会失效。

    cookie虽然是保存在客户端浏览器上的,但是是服务端设置的,浏览器也是可以拒绝服务端的要求,不保存cookies。

    操作cookie其实就是在操作HttpResponse(render,redirect,,,一次请求一次响应):

    obj = HttpResponse('...')
    return obj
     
    obj1 = render(...)
    return obj1
     
    obj2 = redirect(...)
     
    """
    通过对象的方式进行键值对的赋值
    """
     
    # 设置cookie
    obj.set_cookie()
    # 获取cookie
    request.COOKIES.get()
    # 删除cookie
    obj.delete_cookie()
    

    Django中操作Cookie

    获取Cookie

    request.COOKIES['key']
    request.COOKIES.get(key)
    request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    

    参数:

    • default: 默认值
    • salt: 加密盐
    • max_age: 后台控制过期时间

    设置Cookie

    rep = HttpResponse(...)
    rep = render(request, ...)
     
    rep.set_cookie(key,value,...)
    rep.set_signed_cookie(key,value,salt='加密盐', max_age=None, ...)
    

    参数:

    • 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获取(不是绝对,底层抓包可以获取到也可以被覆盖)

    删除Cookie

    def logout(request):
        rep = redirect("/login/")
        rep.delete_cookie("user")  # 删除用户浏览器上之前设置的usercookie值
        return rep
    

    利用cookie写登录功能

    1、先定义路由和视图的关系

    # urls.py
     
    url(r'^login/', views.login)
    

    2、编写登录页面

    # login.html
     
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    </head>
    <body>
    <form action="" method="post">
        <p>username:<input type="text" name="username"></p>
        <p>password:<input type="text" name="password"></p>
        <input type="submit">
    </form>
    </body>
    </html>
    

    3、编写视图函数

    # views.py
     
    # 登录函数
    def login(request):
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            if username == 'jason' and password == '123':
                # 保存用户登录状态
                obj = redirect('/home')
                # 设置cookie
                obj.set_cookie('username', 'jason')
                return obj
        return render(request, 'login.html')
     
     
    # 功能函数
    def home(request):
        # 检验浏览器是否有对应的cookie
        if request.COOKIES.get('username'):
            return HttpResponse('我是home页面,只要登录成功就可以看到我。')
        else:
            return redirect('/login')
    

    上面简单的写了利用cookie的登录功能,但是如果有很多功能都需要验证是否携带cookie,我们不可能在每个功能中去验证,因此需要我们写一个登录认证装饰器。

    登录认证装饰器版

    views.py中添加登录认证装饰器

    # 登录认证装饰器
    from functools import wraps
     
     
    def login_auth(func):
        @wraps(func)
        def inner(request, *args, **kwargs):
            if request.COOKIES.get('username'):
                res = func(request, *args, **kwargs)
                return res
            else:
                return redirect('/login')
        return inner
     
     
    def login(request):
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            if username == 'jason' and password == '123':
                # 保存用户登录状态
                obj = redirect('/home')
                # 设置cookie
                obj.set_cookie('username', 'jason')
                return obj
        return render(request, 'login.html')
     
     
    @login_auth
    def home(request):
        return HttpResponse('我是home页面,只要登录成功就可以看到我。')
    

    高级版登录功能

    需求一:

    当用户访问A网站,但是发现没有登录,将用户跳转到登录页面,用户登录成功后,自动跳转到原来想访问的A页面。

    需求二:

    当用户没有访问其他页面,直接访问登录页面,登录成功后,将用户跳转到home页面。

    request的方法:

    通过request拿到用户想要访问的路径。

    print('request.path_info:',request.path_info)  # 只拿路径部分 不拿参数
    print('request.get_full_path():',request.get_full_path())  # 路径加参数
     
    # 打印结果
    request.path_info: /home/
    request.get_full_path(): /home/?username=jason&password=123
    

    views.py文件改动代码如下:

    # 登录认证装饰器
    from functools import wraps
     
     
    def login_auth(func):
        @wraps(func)
        def inner(request, *args, **kwargs):
            target_url = request.path_info  # 获取路径
            if request.COOKIES.get('username'):
                res = func(request, *args, **kwargs)
                return res
            else:
                return redirect(f'/login/?next={target_url}')  # 将路径拼接到url后面
        return inner
     
     
    def login(request):
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            if username == 'jason' and password == '123':
                # 第一种方式,若next后面没有路径,直接跳转到默认值
                # target_url = request.GET.get('next', '/home/')
                # 第二种方式,对next后面有没有路径进行判断
                target_url = request.GET.get('next')
                if target_url:
                    # 保存用户登录状态
                    obj = redirect(target_url)
                else:
                    obj = redirect('/home/')
                # 设置cookie
                obj.set_cookie('username', 'jason')
                return obj
        return render(request, 'login.html')
    

    退出登录功能,清除cookie

    urls.py新退出登录的路由与视图的关系

    # urls.py
     
    url(r'^logout/', views.logout)
    

    views.py中新增退出的相关视图函数

    # views.py
     
    @login_auth
    def logout(request):
        obj = HttpResponse('注销成功!')
        obj.delete_cookie('username')
        return obj
    

    设置cookie的超时时间

    obj.set_cookie('username', 'jason', max_age=3)
    

    session语法

    # 获取、设置、删除Session中数据
    request.session['k1']
    request.session.get('k1',None)
    request.session['k1'] = 123
    request.session.setdefault('k1',123) # 存在则不设置
    del request.session['k1']
     
     
    # 所有 键、值、键值对
    request.session.keys()
    request.session.values()
    request.session.items()
    request.session.iterkeys()
    request.session.itervalues()
    request.session.iteritems()
     
    # 会话session的key
    request.session.session_key
     
    # 将所有Session失效日期小于当前日期的数据删除
    request.session.clear_expired()
     
    # 检查会话session的key在数据库中是否存在
    request.session.exists("session_key")
     
    # 删除当前会话的所有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失效策略。
    

    保存在服务端上的键值对

    设置:request.session['key'] = value

    • django内部会自动生成一个随机字符串
    • 去django_session表中存储数据,键就是随机字符串,值就是要保存的数据(中间件干的)
    • 将生成的随机字符串返回给客户端浏览器,浏览器保存键值对(sessionid:随机字符串)
    # urls.py
     
    url(r'^set_session/', views.set_session)
     
     
    # views.py
     
    def set_session(request):
        request.session['username'] = 'sean'
        return HttpResponse('set_session')
    

    获取:request.session.get('key')

    • django会在自动取出浏览器的cookie查找sessionid键值对,获取随机字符串
    • 拿着该随机字符串去django_session表中对比数据
    • 如果对比上了,就讲随机字符串对应的数据获取出来并封装到request.session供用户调用
    # urls.py
     
    url(r'^get_session/', views.get_session)
     
     
     
    # views.py
     
    def get_session(request):
        print(request.session.get('username'))
        return HttpResponse('get_session')
    

    django中默认的超时时间为14天

  • 相关阅读:
    6.素数和(素数的判断)
    6.素数和(素数的判断)
    5.明明的随机数(桶排序经典例题)
    5.明明的随机数(桶排序经典例题)
    5.明明的随机数(桶排序经典例题)
    5.明明的随机数(桶排序经典例题)
    Algs4-1.2.11根据Date的API实现一个SmartDate类型
    Algs4-1.2.10编写一个类VisualCounter
    Algs4-1.2.9使用Counter统计BinarySearch检查的key个数
    Algs4-1.2.8引用型变量赋值-数组复制
  • 原文地址:https://www.cnblogs.com/cnhyk/p/12274275.html
Copyright © 2011-2022 走看看