Forms组件的使用
在html表单验证中,需要通过各种信息的验证,比如注册界面的姓名、密码、邮箱、电话等的验证,是否符合定义好的规则,不可能每次都要取出对应的字段一一判断,django内置了Forms组件,可以方便的在HTML中进行校验等信息设置
1.Forms组件的作用
1.数据校验
2.渲染页面
3.渲染错误信息
4.使用局部或者全局的钩子函数
5.设置CSS样式
2.Forms组件的使用
- 1.导入froms模块
from django import forms
- 2.定义一个类继承自forms.Form,编写校验的字段,该字段就是html页面上提交数据上传的字段
class RegisterForms(Form): # 添加的字段类型中的属性,每个子类都继承自field, #field中对应的属性和释义 #required=True, 是否是必须验证,默认为True #widget=None, HTML插件,添加类名,设置placeholder等等 #label=None, 用于生成Label标签或显示内容 #initial=None, 初始值 #help_text='', 帮助信息(在标签旁边显示) #error_messages=None, 错误信息 {'required': '不能为空', 'invalid': '格式错误'} #validators=[], 自定义验证规则 #localize=False, 是否支持本地化 #disabled=False, 是否可以编辑 #label_suffix=None Label内容后缀 name = forms.CharField(min_length=3,max_length=8, label="用户名", error_messages={'min_length':'用户名最少为3位', 'max_length':'用户名最多8位', 'required':'名称不能为空'}) pwd = forms.CharField(min_length=6, max_length=20, label='请输入密码', error_messages={'min_length':'密码最少为6位', 'max_length':'密码最多20位', 'required':'密码不能为空'}) re_pwd = forms.CharField(min_length=6, max_length=20, label='请确认密码', error_messages={'min_length':'密码最少为6位', 'max_length':'密码最多20位', 'required':'密码不能为空'}) phone = forms.CharField(label="请输入手机号码", error_messages={'placerholder': '请输入手机号码'}) email = forms.EmailField(label='请输入邮箱',required=False, error_messages={'invalid':'邮箱格式不合法', 'max_length':'密码最多20位'}) # 对于多传的字段不会出错,cleaned_data中不包含多传的字段# 少传的字段会报错,相当于对应的字段没有值
- 3.在对应的views视图中进行校验,
def form_index(request): post_forms = RegisterForms() error = '' if request.method == 'POST': post_forms = RegisterForms(request.POST) # 4 调用forms的is_valid方法,完成校验,is_valid返回true或者false if post_forms(): register = post_forms.cleaned_data print(register) return HttpResponse('注册成功') else: from django.forms.utils import ErrorDict # 获取全局的error信息,只显示第一个 if post_forms.errors.get('__all__'): error = post_forms.errors.get('__all__')[0] return render(request, 'FormsTest/forms_index.html',locals())
- 4.通过模板渲染,渲染模板有如下几种方式,具体使用如下
forms登录 {% load static %}
- 5.上面只是实现了部分的校验,而且展示的样式需要手动渲染,我们可以在定义模型的时候直接设置好对应的css展示样式和自定义校验规则,比如电话号码的正则校验等等
#导入widgets模块,设置css的展示样式from django.forms import widgets#接下来修改对应的name,pwd,phone等字段,添加新属性,如下添加了占位符和类名这个时候的登录界面就和上面的一样name = forms.CharField(min_length=3,max_length=8, label="用户名", widget=widgets.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入名称(3-8字符)'}), error_messages={'min_length':'用户名最少为3位', 'max_length':'用户名最多8位', 'required':'名称不能为空'}) pwd = forms.CharField(min_length=6, max_length=20, label='请输入密码', widget=widgets.PasswordInput(attrs={'class':'form-control', 'placeholder':'请输入密码(6-20字符)'}), error_messages={'min_length':'密码最少为6位', 'max_length':'密码最多20位', 'required':'密码不能为空'}) re_pwd = forms.CharField(min_length=6, max_length=20, label='请确认密码', widget=widgets.PasswordInput(attrs={'class': 'form-control', 'placeholder': '请确认密码'}), error_messages={'min_length':'密码最少为6位', 'max_length':'密码最多20位', 'required':'密码不能为空'}) phone = forms.CharField(label="请输入手机号码", widget=widgets.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入手机号码'}), error_messages={'placerholder': '请输入手机号码'}) email = forms.EmailField(label='请输入邮箱',required=False, widget=widgets.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入邮箱'}), error_messages={'invalid':'邮箱格式不合法', 'max_length':'密码最多20位'})
- 6.自定义校验规则,有时django自带的校验并不能满足我们所有的需求,比如校验密码输入,不能用特殊字符,手机号码格式定义正则等,这就需要我们自定义规则
#自定义校验规则def mobile_validate(value): mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') if not mobile_re.match(value): raise ValidationError('手机号码格式错误') #在定义字段的时候添加校验规则,校验规则传入的是一个列表,可以有多个校验规则phone = forms.CharField(label="请输入手机号码", validators=[mobile_validate,], widget=widgets.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入手机号码'}), error_messages={'placerholder': '请输入手机号码'})
- 7.自定义钩子,实现自定义的错误提示和校验规则,
#Django中钩子分为局部钩子和全局钩子,# 局部钩子函数(某个字段,自定义的规则,数据库是否存在,以什么开头)# 方法名必须为:clean_字段名def clean_name(self): #获取到当前对象,是cleaned_data之后的数据 name = self.cleaned_data.get('name') if name.startswith('sb'): #以sb开头了返回错误信息,禁止使用sb开头的用户名 raise ValidationError('不能以sb开头') # 数据库中查询有没有这个名称 user = models.UserInfo.objects.filter(username=name).first() if user: raise ValidationError('用户名已存在') return name #全局钩子,方法名必须是clean#校验两次密码是否相同等,def clean(self): pwd = self.cleaned_data.get('pwd') re_pwd = self.cleaned_data.get('re_pwd') if pwd == re_pwd: return self.cleaned_data else: raise ValidationError('两次密码不一致')