Form组件

Form组件能用来干什么?

先提一个需求以此来介绍form组件

1.注册功能
用户输入的用户名中 不能包含'违规信息'
如果包含了 就提示用户 输入的内容不符合社会主义核心价值观
用户输入的密码 不能小于三位
如果密码少于三位  提示用户 密码太短了
(******) 
校验数据通常是前后端都有校验
但是前端校验可有可无 哪怕再牛逼
后端也必须要有校验   反正一句话 前端可有不校验 后端必须校验!!!  

思路:

  1. 首先要搭建前端页面 -----> 渲染页面
  2. 获取前端用户提交的数据体验 ----> 校验数据
  3. 对数据得娇艳的结果 展示到前端页面给用户查看----->展示错误信息

思考一下你要怎么做,算了还是别思考了,直接使用我们的form组件

form组件是一个非常好用的组件,主要功能如下:

  • 生成页面可用的HTML标签
  • 对用户提交的数据检验
  • 还能保留上一次输入的内容
  • 输入内容有错误,就可以在页面相对应位置显示对应的错误信息

使用form组件

添加校验有三种方式

1.字段

2.钩子函数

3.字段中添加正则

自定义信息

1.定义类继承django中的forms.Form类

​ 在类中创建form组件字段

from django import forms
class MyRegForm(forms.Form):
   username = forms.CharField(min_length=3,max_length=8)
   password = forms.CharField(min_length=3,max_length=8)
   email = forms.EmailField()
    

相关用法:

min_length:即为char字段最短长度
max_length:即为char字段最长长度
label  对象.字段.label获得的值,默认是首字母大写的字段名
error_messages:输入显示的错误信息
required:用户没有输入文本框的内容错误信息
min_length:不满足最短长度的错误信息,
max_length:不满足最长长度的错误信息,
invalid: 格式错误,
initial: 前端input框内,默认value

###widget字段####   
widget=forms.widgets.TextInput(attrs={'class':'value'})
Textinput 规定input是text类型,也可以为Password,Email类型
attrs给input框添加属性,可以是类,id,样式,js任意
如何改变input框的type属性值
        widget= widgets.TextInput()
        widget=widgets.PasswordInput()
如何让forms组件渲染出来的input框有form-control类属性
        widget= widgets.TextInput(attrs={'class':'form-control others'})  # 如果有多个类属性 空格隔开
        widget=widgets.PasswordInput(attrs={'class':'form-control others'})
        
           

校验数据

在此直接介绍一下pycharm里面功能,python Console,可以帮我们搭配好django环境然后还会对输入返回结果,Out即为返回结果.

from app01 import views
# 给自定义类传字典
obj= views.MyRegform({'username':'jh','password':'12','email':'129308'})

# 2判断数据是否全部合法
obj.is_valid() # 只有数据全部符合要求才会是True
Out[4]:False
    
# 3.查看符合条件校验规则的数据
obj.cleaned_data  # 返回字典形式
Out[5]: {'username': 'jason'}
    
# 4.查看错误不符合条件数据以及不符合原因
obj.errors
Out[6]: 
            {
                'password': ['Ensure this value has at least 3 characters (it has 2).'],
                'email': ['Enter a valid email address.']
             }
# 5.检验数据的时候,默认情况下username和password都必须传值
obj = views.MyRegForm({'username':'jason','password':'123'})
obj.is_valid()
            Out[12]: False
            obj.errors
            Out[13]: {'email': ['This field is required.']}
                
# 6.默认情况可以多传 但是不能少传
views.MyRegForm({'username':'jason','password':'1233','email':'123@qq.com','xxx':'ooo'})
            obj.is_valid()
            Out[15]: True

如何渲染页面?

我们已经得到了结果,最终我们是要将结果渲染出来的,那么我们怎么做才能在前端页面上展示出来才能渲染页面呢?

注意:forms组件只会帮你渲染获取用户输入标签,提交按钮还是要自己手动写的

三种渲染前端页面方式

  1. as_p & as_ul
    封装程度过高,样式&参数不方便调整,可扩展性差,不推荐使用
{{form.obj.as_p}} 作为p标签形式展示
{{from.obj.as_ul}} 作为ul标签形式展示
  1. 扩展性高,需要手写大量代码,不推荐
<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>
  1. 推荐理由:代码量少扩展性高
{% for foo in form_obj %}
<p>{{ foo.label }}{{ foo }}</p>
{% endfor %}

MyRegForm对象.字段.label 可以获得字段的label值
MyRegForm对象.字段   生成对应的input框
MyRegForm对象.字段.errors[0]  获得该字段的错误信息
对MyRegForm对象进行for循环,循环出的是MyRegForm对象.字段

浏览器会自动帮你做校验,所以我们需要取消自动的校验,只需要在form表中添加一个参数novalidate关闭验证

<form action="" method="post" novalidate>
    
展示错误信息   用对象点errors.0
<form action="" method="post" novalidate>
    {% for foo in form_obj %}
    <p>
        {{ foo.label }}:{{ foo }}
        <span style="color: red">{{ foo.errors.0 }}</span>
    </p>
    {% endfor %}
    <input type="submit">
</form>

form组件之钩子函数

我们还可以在Form类中定义钩子函数,实现自定义的验证功能.

全局钩子

需要对多个字段添加校验的时候,使用全局钩子

def clean(self):
    	# 拿到了里面的username来看一下
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if not password == confirm_password:
			# 不相等,就将错误信息丢到error里面去
            self.add_error('confirm_password','两次密码不一致')
        return self.cleaned_data #这里就把全部都还回去了。

局部钩子

需要对某一个字段进行额外校验,使用局部钩子

 # 当你需要对某一个字段数据进行额外的一些列校验 你可以考虑使用钩子函数
            # 针对单个字段的  使用局部钩子
def clean_username(self):
        username = self.cleaned_data.get('username')
        if 'xxx' in username:
            #不符合的话就丢进 error 里面去
            self.add_error('username','不能')
        return username 

总结

使用钩子函数要有返回值,局部返回钩住的数据,全局钩子返回self.cleaned_data全部数据

字段中利用正则添加校验规则

from django import forms
from django.forms import Form
# 1.导入django中的正则
from django.core.validators import RegexValidator

# 2.在字段中添加关键字参数validators
class MyForm(Form):
    user = forms.CharField(
        validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],)

validators 对应的值是列表,可以放多个正则,RegexValidator(r'正则表达式', '报错信息'),

其它form组件字段

email = forms.EmailField(label='邮箱',error_messages={
        'required':'邮箱不能为空',
        'invalid':'邮箱格式不正确'
},required=False,widget=widgets.EmailInput(attrs={'class':'form-control'}))

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



gender = forms.ChoiceField(
    choices=((1, "男"), (2, "女"), (3, "保密")),
    label="性别",
    initial=3,
    widget=widgets.RadioSelect()
)




hobby = forms.ChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=3,
    widget=widgets.Select()
)

hobby1 = forms.MultipleChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=[1, 3],
    widget=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()
)
posted @ 2019-11-04 22:14  Huise.J  阅读(164)  评论(0编辑  收藏  举报