zoukankan      html  css  js  c++  java
  • django之forms组件

    django为我们提供了forms组件,可以让我们非常方便的渲染前端页面、接收及验证前端发送到后端的数据。、


    forms组件不会将用户的输入清空

    1.forms组件基本使用

    后端代码

    views.py
    ---------------------------------------
    from django import forms
    class MyRegForm(forms.Form):
        username = forms.CharField(max_length=8, min_length=3)
        password = forms.CharField(max_length=8, min_length=3)
        email = forms.EmailField()
        
    def register(request):
        # 生成一个自定义的form组件对象
        form_obj = MyRegForm()
        if request.method == 'GET':
            return render(request, 'register.html', locals())
        form_obj = MyRegForm(request.POST)
        return render(request, 'register.html', locals())
    

    前端代码

    <form action="" method="post" novalidate>
        {% for input_obj in form_obj %}
        <p>
            <label for="{{ input_obj.id_for_label }}">
                {{ input_obj.label }}
            </label>
            {{ input_obj }} 
            <span>{{ input_obj.errors.0 }}</span>
        </p>
        {% endfor %}
        <input type="submit" value="提交">
    </form>
    

    后端常用方法

    # form_obj本质上是根据我们定义的类封装了html代码,根据django的模版语法再渲染到html文件中
    # form_obj常用方法
    
    # 1.初始化form组件对象
    form_obj = MyRegForm(request.POST)
    
    # 2.检验form中的数据是否全部合法(可多不可少)
    form_obj.is_valid()
    
    # 3. 返回验证通过的数据。
    form_obj.cleaned_data
    
    # 4.如何获取校验失败及失败的原因
    form_obj.errors
    
    {
        'password': ['Ensure this value has at least 3 characters (it has 2).'],
        'email': ['Enter a valid email address.']
    }
    

    前端渲染

    <p>第一种渲染方式:多个p标签  本地测试方便 封装程度太高了 不便于扩展</p>
    {{ form_obj.as_p }}
    {{ form_obj.as_ul }}
    {{ form_obj.as_table }}
    
    <p>第二种渲染方式:  扩展性较高 书写较为繁琐</p>
    <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 }}
    
    <p>第三种渲染方式  推荐使用</p>
    如前端代码所示,使用for循环
    

    要注意的是forms组件在前端自带校验功能,但前端源码容易被修改,必须在后端进行校验后再对数据进行操作。

    前端校验只可作为用户提示。

    <form action="" method="post" novalidate>  # 取消前端校验
    

    2.常用参数

    label  # 每个input的标签内容,默认为字段名首字母大写
    
    error_messages # 自定义报错的提示信息
    username = forms.CharField(max_length=8, min_length=3,
                               error_messages={
                                   'max_length': '最大长度为8',
                                   'min_length': '最小长度为3',
                                   'required':'不能为空',    # 为空时的提示信息
                               })
    
    required  # 默认为True表示必填
    
    widget # 控制type的类型及属性
    password = forms.CharField(max_length=8,min_length=3,
                     widget=forms.widgets.PasswordInput(attrs={'class':'form-control c1 c2'})
                             )
    

    3.钩子函数

    django中勾子函数分为全局钩子和局部钩子。全局勾子函数一般用于字段与字段之间的关系处理,如注册时两次密码确认。局部勾子一般用于某个字段的检验,如检查用户名是否有非法字符。

    def clean(self):
    #    print('全局钩子....')
    #    username = self.cleaned_data.get('username')
    #    print(username,'全局钩子','username')
    #    password = self.cleaned_data.get('password')
    #    print(password, '全局钩子', 'password')
    
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if password != re_password:
            self.add_error('re_password','两次密码不一致')
            
        return self.cleaned_data # 注意return
    
    def clean_username(self):
        print('局部钩子...')
        username = self.cleaned_data.get('username')
        if '666' in username:
            self.add_error('username','用户名不能包含666')
    
        return username # 如果不return,clean_data中username就为空
    

    钩子函数的命名非常形象,钩子就像是针对钩取对象中的某个字段进行处理,然后将改字段返回,勾过来记得放回去。

    钩子函数的几个注意点:

    • 勾出来的数据一定要返回
    • 局部钩子函数只有在这个局部的字段通过基本的校验才会被执行(如用户名如果不满足3-8位的要求,就不会去执行clean_username)
    • 全局钩子则无论如何都会执行

    4.正则校验

    from django.core.validators import RegexValidator
    
    phone = forms.CharField(
        validators=[
            RegexValidator(r'^[0-9]+$', '请输入数字'),
            RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
        ]
    )
    # 其余字段做了解
    

    5.django中的cookie和session

    cookie是一种技术,大多情况下用来验证用户是否登录,在用户登录成功后返回给用户的一段随机字符串。当用户接下来访问其他页面时,可通过cookie来识别用户的身份

    session是存储在服务端的key,value的一组对应关系。一个cookie对应一个value值,这个值通常是经过序列化后加密的。

    cookie

    #  设置cookie的方法
    obj = HttpResponse('....')
    obj = render('....')
    obj = redirect('....')
    obj.set_cookie('k1','v1')
    # 删除cookie
    obj.delete_cookie('k1')
    
    # 获取cookie
    request.COOKIES.get('k1')
    
    '''
    cookie中可以存放用户的一些信息
    例如登录前访问的url,在登录后实现自动跳转
    '''
    

    session

    # 设置session
    request.session['name'] = 'egon'
    request.session['password'] = '123'
    '''
    1.django内部会自动生成一个随机字符串
    2.去django_session表中存储数据,键时随机产生的字符串,值实际上是一个序列化后的字典经过加密产生的字符串
    3.将生成好的key返回给客户端浏览器存储在COOKIE 键名为sessionId中。
    '''
    
    # 获取session
    request.session.get('name')
    '''
    1.django会自动去浏览器的cookie中查找sessionId的键的值
    2.将该值去数据库django_session的表中比对
    3.如果比对上了,就将对应的value值解密反序列化后封装到request.session中
    '''
    
    # 删除session
    # 删除当前会话的所有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失效策略。
    '''
    

    6.其余不常用字段

    gender = forms.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
        initial=3,
        widget=forms.widgets.RadioSelect()
    )
    
    hobby = forms.ChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=3,
        widget=forms.widgets.Select()
    )
    hobby1 = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple()
    )
    keep = forms.ChoiceField(
        label="是否记住密码",
        initial="checked",
        widget=forms.widgets.CheckboxInput()
    )
    hobby2 = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()
    )
    
  • 相关阅读:
    bzoj4804
    bzoj2962
    bzoj4827
    bzoj2553
    bzoj3611
    BZOJ 1636: [Usaco2007 Jan]Balanced Lineup
    BZOJ 1635: [Usaco2007 Jan]Tallest Cow 最高的牛
    BZOJ 1634: [Usaco2007 Jan]Protecting the Flowers
    BZOJ 1631: [Usaco2007 Feb]Cow Party
    BZOJ 2582: [Usaco2012Jan]Bovine Alliance
  • 原文地址:https://www.cnblogs.com/Ghostant/p/12189242.html
Copyright © 2011-2022 走看看