前戏:
在注册页面获取到用户名密码,提交到后端进行校验,在返回结果给出提示
在不用ajax的情况下,需要有前端页面的编写,后端的校验编写和返回给前端页面的提示信息展示编写
forms组件可以一条龙服务,完成上面三件事:标签渲染,数据校验,展示信息
from django import forms
class MyForm(forms.Field):
# username字段最少不能少于6位,最对不能大于9位,label的值在前端展示时使用
usernaem = forms.CharField(max_length=9,min_length=6,label='用户名')
# password字段最大值不能超过1029
password = forms.IntegerField(max_value=1029,label='密码')
# email字段必须符合邮箱规则
email = forms.EmailField(label='邮箱')
# 1.类加括号 传入字典即可
form_obj = MyForm({'username':'jason','password':'123','email':'嘿嘿嘿'})
# 2.判断数据是否合法(只有全部合法结果才为True)
form_obj.is_valid()
False
# 3.查看所有合法的数据
form_obj.cleaned_data
{'username': 'jason', 'password': 123}
# 4.查看所有不合法的数据及原因
form_obj.errors
{'email': ['Enter a valid email address.']}
# 校验数据可以多传 但是不能少传(默认必填)
from组件渲染标签
def login(request):
# 1.先生成一个对象
form_obj = MyForm()
# 2.将该对象传递给html页面
return render(request,'login.html',locals())
方式1
简单粗暴 一次性渲染label文本和input框
{{ form_obj.as_p }}
"""
优点:速度快
缺点:封装程度高 不便于扩展
"""
方式2
一步步需要自己书写字段对象
{{ form_obj.username.label }}
{{ form_obj.username }}
"""
优点:字段之间相互解耦
缺点:字段多的时候书写麻烦
"""
方式3
for循环依次获取每个字段对象
{% for form in form_obj %}
<p>
{{ form.label }}:{{ form }}
</p>
{% endfor %}
'''推荐使用'''
# forms组件无法渲染提交按钮和form标签都需要你自己编写
# 使用forms组件渲染标签后在获取用户数据的时候,浏览器会自动帮助我们校验数据,但浏览器层面的数据校验弱不禁风没有实际意义
# 取消浏览器的自动校验数据的功能
<form action="" method="post" novalidate>
# 自己校验数据
def login(request):
# 1 先生成一个对象
form_obj = MyForm()
# 2.1 判断请求方式,如果是post请求,则进行数据校验
if request == 'POST':
# 获取用户数据并校验,request.POST得到的数据刚好是一个字典
form_obj = MyForm(request.POST)
if form_obj.is_valid():
return HttpResponse('登录成功')
# 2.2 get请求之间将对象传递给html页面
{% for form in form_obj %}
<p>
{{ form.label }}:{{ form }}
{{ form.errors.0 }}
</p>
{% endfor %}
max_length 最大范围
min_length 最小范围
label 字段文本内容
required 字段是否必填,默认True
error_messages 定义提示信息
widget 定义字段类型和属性
validators 额外的校验功能(一般都是正则)
initial 设置默认值
# 钩子函数提供了更加复杂的与业务相关的校验功能,钩子函数其实就是在书写在forms类的过程中定义方法
# 钩子函数进行校验是数据校验的最后一个阶段
# 局部钩子(单个字段进行额外的校验)
# 校验当前用户名是否存在
def clean_username(self):
# 获取用户名
username = self.cleaned_data.get('username')
# 查询数据并做判断
if username == '':
self.add_error('username','用户名已存在')
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
# 单选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()
)