django之forms组件 一.forms组件基本用法 二.渲染页面三种方式 三.展示错误信息 四.钩子函数(HOOK) 五.forms组件其他字段及操作方式  

forms组件能够直接帮助我们完成三步操作:

 1.渲染前端页面

 2.校验数据是否合法

    3.展示错误信息

1.写一个基础的forms.Form的类

from django import 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.基本使用

在django中 python console中  首先导入  from app01 import views

#1.将需要校验的数据 以字典的方式传递给自定义的类 实例化产生对象
form_obj = views.LoginForm({'username':'jason','password':'123','email':'123'})

#2.如何查看数据是否全部合法
form_obj.is_valid()  # 只有所有的数据都符合要求 才会是TrueFalse

#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组件不会去校验  也就意味着多传一点关系都没有

二.渲染页面三种方式

第一种:

<p>第一种渲染页面的方式(封装程度太高 一般只用于本地测试  通常不适用)</p>
<form action="" method="post">
    {{ form_obj.as_p }}
    {{ form_obj.as_ul }}
    {{ form_obj.as_table }}
    <input type="submit">
</form>

第二种:

<p>第二种渲染页面的方式(可扩展性较高 书写麻烦)</p>
<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>

第三种:

<p>第三种渲染页面的方式(推荐)</p>
{% for foo in form_obj %}
<p>{{ foo.label }}{{ foo }}</p>
{% endfor %}

注意事项:

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

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

前端取消浏览器校验功能  

  form标签指定novalidate属性即可

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

三.展示错误信息

视图 views.py

from django import forms

class RegForm(forms.Form):
    username = forms.CharField(max_length=8,min_length=3)
    password = forms.CharField(max_length=8,min_length=5)
    email = forms.EmailField()  #必须是email格式


def reg(request):
    form_obj = RegForm()
    if request.method == 'POST':
        form_obj = RegForm(request.POST)
    return render(request,'register.html',locals())

模板层:

<form action="" method="post" novalidate>
    {% for form in form_obj %}
        <p>{{ form.label }}:{{ form }}
        <span>{{ form.errors.0 }}</span>
        </p>

    {% endfor %}

    <input type="submit">
</form>

补充:也可以用正则来限制校验规则

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类中书写方法即可

局部钩子

# 局部钩子(针对某一个字段做额外的校验)   校验用户名中不能包含666 一旦包含 提示
            def clean_username(self):
                username = self.cleaned_data.get('username')
                if '666' in username:
                    self.add_error('username','光喊666是不行的 你得自己上')
                return username

全局钩子

# 全局钩子(针对多个字段做额外的校验)    校验用户两次密码是否一致
            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()
                )