• Django之form组件用法


    form介绍

      form组件常用于对用户输入的内容做效验,比如效验用户是否输入,输入的长度和格式是否正确。如果用户的输入有错误就会在页面相对应的位置,显示出与之对应的错误信息。

    orm组件的主要功能如下:①生成页面可用的HTML标签,②对用户提交的数据进行校验,③保留上次输入内容。

    form组件能直接完成以下的三步操作:

      1、前端页面搭建              ---------> 渲染页面

      2、将数据传输到后端做效验    ---------> 效验数据

      3、展示错误信息            ---------> 展示信息

     forms组件基本用法

    1.写一个基于forms.From的类

    from django import forms   # 引入Django中的forms模块
    
    class LoginForm(forms.Form):
    username = forms.CharField(max_length=8,min_length=3)  # 用户名最长八位最短三位
    password = forms.CharField(max_length=8,min_length=5)  # 密码最长八位最短五位
    email = forms.EmailField()  # email必须是邮箱格式

    2.form基本使用

    from app01 import views
    
    #1.将需要校验的数据,以字典的方式传递给自定义的类,实例化产生对象
    form_obj=views.LoginForm({'username':'jason','password':'123','email':'123'})
    
    #2.如何查看数据是否全部合法
    form_obj.is_valid()  # 只有所有的数据都符合要求 才会是True
    >>>:False
    
    #3.如何查看错误原因
    form_obj.errors
    >>>:{'password': ['Ensure this value has at least 5 characters (it has 3).'], 'email': ['Enter a valid email address.']}
    
    #4.如何查看通过校验的数据
    form_obj.cleaned_data  
    >>>:{'username': 'jason'}

    注意事项:

      1.自定义类中所有的字段默认都是要传值的。意味着少传会出现报错。

      2.可以额外传入类中没有定义的字段名,forms组件不会去效验。意味着多传不会发生报错。

    渲染页面的三种方式

    #1.第一种渲染页面的方式(封装程度太高 一般只用于本地测试  通常不适用)
    {{ form_obj.as_p }}  
    {{ form_obj.as_ul }}
    {{ form_obj.as_table }}
                    
    #2.第二种渲染页面的方式(可扩展性较高 书写麻烦)
    <p>{{ form_obj.username.label }}{{ form_obj.username }}</p>
    <p>{{ form_obj.password.label }}{{ form_obj.password }}</p>
    <p>{{ form_obj.email.label }}{{ form_obj.email }}</p>
                    
    #3.第三种渲染页面的方式(推荐)
    {% for foo in form_obj %}
        <p>{{ foo.label }}{{ foo }}</p>
        <p>{{ foo.label.0}}</p>    # 按照后端定义的内容提示
    {% endfor %}

    注意事项:

      1.forms组件在帮你渲染页面的时候,只会渲染获取用户输入的标签,提交按钮(submit)仍需要你手动添加。

      2.input框中的label注释,在不指定的情况下,默认用类中字段的首字母大写。

      3.效验数据的时候可以前后端都效验,做一个双重验证。前端效验可有可无,但后端的效验必须要有。可以通过指定novalidata属性来取消前端效验。

    <form action="" method='post' novalidate></form>

     展示错误信息

    {% for foo in form_obj %}
        <p>{{ foo.label }}:{{ foo }}
            <span>{{ foo.errors.0 }}</span>
        </p>
    {% endfor %}
    
    
    # 后端代码
     password = forms.CharField(max_length=8,min_length=5,label='密码',error_messages={
         'max_length':'密码最大八位',
         'min_length':'密码最小五位',
          'required':'密码不能为空'
         },required=False,
    validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')])  # 密码最长八位最短五位

    钩子函数(HOOK)

    forms组件暴露给用户,可以自定义的校验规则。用法:在自定义的form类中书写方法即可

    1.局部钩子

      针对某一个字段做额外的校验,校验用户名中不能包含666,一旦包含会有提示

    def clean_username(self):
        username = self.cleaned_data.get('username')
        if '666' in username:
            self.add_error('username','不能只喊666')
        return username

    2.全局钩子

      针对多个字段做额外的校验,校验用户两次密码是否一致

    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

    forms组件其他字段及操作方式

      required -------> 是否必填

      label ------->  注释信息

      error_messages ------->  报错信

      initial ------->  默认值

      widget ------->  控制标签属性和样式

        widget=widgets.PasswordInput()  控制标签属性

        widget=widgets.PasswordInput(attrs={'class':'form-control c1 c2','username':'jason'})

    # 单选的radio框
    gender = forms.ChoiceField(
      choices=((1, ""), (2, ""), (3, "保密")),
      label="性别",
      initial=3,
      widget=forms.widgets.RadioSelect()
    )
    # 单选select
    hobby = forms.ChoiceField(
      choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
      label="爱好",
      initial=3,
      widget=forms.widgets.Select()
    )
    # 多选的select框
    hobby1 = forms.MultipleChoiceField(
      choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
      label="爱好",
      initial=[1, 3],
      widget=forms.widgets.SelectMultiple()
    )
    # 单选的checkbox
    keep = forms.ChoiceField(
      label="是否记住密码",
      initial="checked",
      widget=forms.widgets.CheckboxInput()
    )
    # 多选的checkbox
    hobby2 = forms.MultipleChoiceField(
      choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
      label="爱好",
       initial=[1, 3],
      widget=forms.widgets.CheckboxSelectMultiple()
    )

    cookie与session

      http协议是无状态的,无法记录用户状态 。

    cookie

      cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对。

      工作原理:当你登陆成功之后,浏览器上会保存一些信息,下次再访问的时候,就会带着这些信息去访问服务端,  服务端通过这些信息来识别出你的身份。

      cookie虽然是写在客户端浏览器上的,但是是服务端设置的。浏览器可以选择不服从命令,禁止写cookie,其结果是无法在浏览器里面进行登录。

    查看Cookie

      我们使用Chrome浏览器,打开开发者工具。

     操作cookies

      Django返回给客户端浏览器的都必须是HTTPResponse对象。

    obj1 = HttpResponse()
        return obj1
    obj2 = render()
        return obj2
    obj3 = redirect()
        return obj3
    
    #设置cookie利用的就是HTTPResponse对象。
        obj.set_cookie('k1', 'v1')
    #获取cookie
        request.COOKIE.get()
    #删除cookie
        obj.delete_cookie('k1')  # 删除用户浏览器上之前设置的usercookie值
    #设置超时时间 max_age=None, 超时时间 expires=None,超时时间(IE requires expires, so set it if hasn't been already.)

    session

      session虽然是保存在服务器上的键值对,但是它是依赖于cookie工作的。服务器返回给浏览器一个随机的字符串,浏览器以键值对的形式保存。随机字符串(sessionid)。

      浏览器在访问服务端的时候,就会将随机字符串携带上,后端先获取随机字符串,然后与后端的数据记录进行对比。每条随机字符串对应的是一串数据。

    设置session

    request.session['name'] = 'jason'
        """
        上面这一句话发生了三件事
            1.django 内部自动生成一个随机字符串
            2.将随机字符串和你要保存的数据 写入django_session表中(现在内存中生成一个缓存记录 等到经过中间件的时候才会执行)
            3.将产生的随机字符串发送给浏览器写入cookie
        sessionid:随机字符串
        """    

     获取session

    request.session.get('name')
    """
        上面这一句话发生了三件事
            1.django内部会自动从请求信息中获取到随机字符串
            2.拿着随机字符串去django_session表中比对
            3.一旦对应上了就将对应的数据解析出来放到request.session中    
        """

    注意事项:

      1.django session默认的超时时间是14天。

      2.django_session表中的一条记录针对的仅是一个浏览器。如果想要增加记录,得启动其他的浏览器。

    session的相关操作

    #删除当前会话的所有session数据。
        request.session.delete()  # 删除的只是浏览器中的session信息
    #删除当前的会话数据并删除会话的Cookie。
        request.session.flush()  #将浏览器和服务端的信息都删除
    #作用:确保前面的会话数据不可以被用户的浏览器再次访问
    
    # 设置会话Session和Cookie的超时时间
        request.session.set_expiry(value)
            * 如果value是个整数,session会在些秒数后失效。
            * 如果value是个datatime或timedelta,session就会在这个时间后失效。
            * 如果value是0,用户关闭浏览器session就会失效。
           * 如果value是None,session会依赖全局session失效策略。
    #总结:在后期可以将一些数据保存到session表中,保存的数据可以在后端的任意位置获取到。

     session流程解析图

  • 相关阅读:
    js数组扁平化
    react 监听页面滚动
    package.json 里的 dependencies和devDependencies区别
    背景图自适应屏幕居中显示,且不变形
    antd table 点击行触发radio 或 checkbox
    使用antd Table + mobx 处理数组 出现的一系列问题
    定时刷新页面或请求接口
    添加索引,联合唯一索引
    添加 查看 和删除 索引
    phpEXCEL如何设置单元格格式为百分比
  • 原文地址:https://www.cnblogs.com/blue-tea/p/11578166.html
Copyright © 2020-2023  润新知