一.Django Form组件
# 定义Form组件
from django import forms
class RegForm(forms.Form):
username = forms.CharField(lable='用户名', min_length=6)
password = forms.ChatField(lable='密码')
# 使用Form组件需要实例化From类
def register(request):
# 实例化RegForm类
form_obj = RegForm()
return render(request, 'register.html', context={'form': form_obj})
# 在模板中使用
<form action="" method="post" novalidate> # novalidate 不在前端做校验
{% csrf_token %}
# 一次性生成所有的input框
{{ form_obj.as_p }}
<button>注册</button>
</form>
{{ form_obj.user }} 该字段的input框
{{ form_obj.user.label }} 该字段的提示信息
{{ form_obj.user.id_for_label }} 该字段的input框的id
{{ form_obj.errors }} 所有字段的错误
{{ form_obj.username.errors.0 }} 该字段的错误
使用form组件校验数据
def register(request):
from_obj = RegForm()
if request.method == 'POST':
form_obj = RegForm(request.POST) # 包含了用户提交的数据
if form.obj.is_valid(): # 对数据进行校验
#is_valid返回一个错误字典
#只要这个字典中有值,就意味着发生了错误,那么校验失败,如果字典中没有值,那么校验成功
# 校验成功
return HttpResponse('注册成功')
return render(request, 'register.html', context={'form_obj': form_obj})
Form组件常用字段
# 文本类型
forms.CharField()
# 单选择类型 默认就是select
forms.ChoiceFiedld(choices=(('1', '男'), ('2', '女')))
# 多选类型 默认就是select
forms.MultipleChoiceField()
# 邮箱类型
forms.EmailField()
常用的字段参数
initial='xx' # 设置默认值
# 自定义错误提示
error_messages = {
'required': '不不能为空',
'min_length': '用户名最少6位'
}
widget = forms.PasswordInput # 插件 修改input的type
widget = forms.CheckboxInput # 单选Checkbox
required = True # 是否必填
disabled = True # 是否禁用
choices # 用户选择的数据(元组的格式)
validators = [校验函数] # 校验参数
校验器
# 1.定义函数
def check_name(value):
if 'cjh' in value:
raise ValidationError('不符合规则')
# 将校验函数加入到Form组件中
class RegFrom(forms.Form):
username = forms.CharField(validators=[check_name])
# 2.使用内置函数 校验手机号验证
class RegFrom(forms.Form):
username = forms.CharField(validators=[check_name])
phone = forms.CharFiedld(validtors=[RegexValidator(r'^1[3-9]\d{9}$', '手机格式不正确')])
钩子函数
1.局部钩子
class RegForm(forms.Form):
username = forms.CharField()
# 定义局部钩子函数clean_字段(只针对于一个字段username做校验)
def clean_username(self):
value = self.cleaned_data.get('username') # 获取清理后的数据
if 'cjh' in value:
raise ValidationError('不符合规范')
return value
2.全局钩子
class RegForm(forms.Form):
username = forms.CharField()
pwd = forms.CharField()
re_pwd = forms.CharField()
# 定义全局钩子函数 clean
def clean(self):
pwd = self.cleaned_data.get('pwd') # 获取清理后的数据re_
re_pwd = self.cleaned_data.get('re_pwd')
if pwd != re_pwd:
# 将错误信息加入到某个字段中
self.add_error('re_pwd', '两次密码不一致')
raise ValidationError('两次密码不一致')
return self.cleaned_data
is_valid()的流程
1.执行一个full_clean方法
1.1定义一个错误字典和cleaned_data = {} # 存放已经校验过的数据
1.2执行self._clean_fields()
循环所有的字段
对一个字段进行内置的校验、校验器的校验、局部钩子的校验
校验不通过,错误字典中有该字段的错误信息
所有校验通过,self.cleaned_data有该字段的值
1.3执行全局钩子
二.ModelForm
# ModelForm按照models的字段添加form的字段
class RegForm(forms.ModelForm):
# Meta是对默认的字段进行设置,而在RegForm下面可以重写或者新增字段
password = forms.CharField(widget=forms.PasswordInput, label='密码', min_length=6,
error_messages={'required': '密码必须填写'})
re_password = forms.CharField(widget=forms.PasswordInput, label='确认密码', min_length=6)
class Meta:
# 根据模型User形成form
model = models.User
# 从User模型中选择要形成的form字段
# fields = '__all__' # 所有的
fields = ['username', 'password', 'position', 'company', 'phone'] # 某些字段
# exclude = [''] # 排除哪些字段
# labels = {'username': '用户名'}
widgets = {
# 插件
'password': forms.PasswordInput # 密码字段设置为密文
}
error_messages = {
# 设置错误信息
'username': {
'required': '用户名必须填写'
}
}
# 校验手机号码的局部钩子函数
def clean_phone(self):
phone = self.cleaned_data.get('phone')
if re.match(r'^1[3-9]\d{9}$', phone):
return phone
raise ValidationError('手机号格式不正确')
# 校验两次密码的全局钩子
def clean(self):
self._validate_unique = True # 校验数据库唯一
password = self.cleaned_data.get('password')
re_password = self.cleaned_data.get('re_password')
if password == re_password:
return self.cleaned_data
self.add_error('re_password', '两次密码不一致')
raise ValidationError('两次密码不一致')
# 与RegForm对应的视图函数
def register(request):
# 实例化RegForm类,构成表单
regform_obj = RegForm()
# 判断请求方法是否为POST
if request.method == 'POST':
# 获取RegForm中用户提交的数据
regform_obj = RegForm(request.POST)
# 判断获取的regform_obj对象内容是否有错
if regform_obj.is_valid():
# 注册成功
# 将数据插入到用户表中
# regform_obj.cleaned_data.pop('re_password')
# models.User.objects.create(**regform_obj.cleaned_data) # **字典 将字典打散,变为一个一个的键值对
# ModelForm可直接使用save将数据保存到数据库
regform_obj.save()
return redirect('login')
return render(request, 'register.html', {'regform_obj': regform_obj})
# register.html 模板中
{{ regform_obj.字段 }} # input框
{{ regform_obj.字段.label }} # label提示
{{ regform_obj.字段.id_for_label }} # input框的id
{{ regform_obj.字段.errors.0 }} # 字段错误提示