forms组件
目录
form组件
一、前戏
编写用户登录功能并且校验数据返回提示信息(form表单)
写一个注册功能
1.获取用户名和密码,利用form表单提交数据
2.在后端判断用户名和密码是否符合一定的条件
3.用户名不能是jason,密码不能是123
'''符合条件需要你将提示信息动态的展示到前端页面'''
前端
<form acyion="" method="post">
<p>username:
<input type="text" name="username">
{# 行内标签 get请求为空 不占任何标签 post请求有值 就可以点到对应的数据 #}
<span style="color: red">{{ data_dict.username }}</span>
</p>
<p>password:
<input type="text" name="password">
{# 行内标签 get请求为空 不占任何标签 post请求有值 就可以点到对应的数据 #}
<span style="color: red">{{ data_dict.password }}</span>
</p>
<input type="submit" class="btn btn-info">
</form>
后端
def ab_form_func(request):
# 不能使用ajax,那么它后是影响的整个页面
data_dict = {'username': '','password': ''}
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'jason':
data_dict['username'] = '不能使用jason'
if password == '123':
data_dict['password'] = '密码不能是123'
return render(request, 'ab_form.html', locals())
二、form组件
1.主要功能
1.数据校验
支持提前设置各种校验跪着 之后自动校验
2.渲染页面
支持直接渲染获取用户数据的各种标签
3.展示信息
支持针对不同的校验失败展示不同的提示
2.form组件基本使用
<1>.form类型创建
首先需要导入模块
from django import forms
然后创建类
from django import forms
class MyForm(forms.Form):
username = forms.CharField(min_length=3, max_length=8) # username字段最少三个字符最大八个字符
age = forms.IntegerField(min_value=0, max_value=200) # 年龄最小0 最大200
email = forms.EmailField() # 必须符合邮箱格式
<2>.校验数据
测试环境两种方式
1.测试环境的准备 可以自己拷贝代码准备
2.其实在pycharm左下角已经帮你准备了一个测试环境"python console"
from app01 import views
# 1.将待校验的数据组织成字典的形式传入即可
form_obj = views.MyForm({'username':'jason','password':'123','email':'123'})
# 2.判断数据是否合法
'''注意该方法只有在所有的数据全部合法的情况下才会返回True'''
form_obj.is_vaild()
False
# 3.查看所有校验通过的数据
form_obj.cleaned_data
{'username': 'jason', 'password': '123'}
# 4.查看所有不符合校验规则以及不符合的原因
form_obj.errors
{
'email': ['Enter a valid email address.']
}
校验数据只校验类中出现的字段,多传不影响,多传的字段直接忽略
form_obj = views.MyForm({'username':'jason','password':'123','email':'123@qq.ccom','hobby':'study'})
form_obj.is_valid()
True
校验数据 默认情况下 类里面所有的字段都必须传值
form_obj = views.MyForm({'username':'jason','password':'123'})
form_obj.is_valid()
False
也就意味着校验数据的时候 默认情况下数据可以多传但是绝对不可以少传
<3>.渲染标签功能
类中以外的所有标签都不会自动渲染,需要自己编写
方式1(封装程度高,扩展性差 主要用于本地测试)
{{ form_obj.as_p }}
{{ form_obj.as_ul }}
{{ dorm_obj.as_table }}
这种方法的缺点是封装程度太高了,什么都是人家渲染出来的,并且带来label和p标签,扩展性差
渲染成无序列表形式
方式2(封装程度低,扩展性好,编写困难)
{{ form_obj.name.label }}
{{ form_obj.name }}
{{ form_obj.age.label }}
{{ form_obj.age }}
{{ form_obj.email.label }}
{{ form_obj.email }}
方式3(推荐使用)
{% for form in form_obj %}
<p>{{ form.label }}{{ form }}</p>
{% endfor %}
只渲染类里写的字段,如果要使用按钮之类的需要自己写,类中以外的字段都不会自动渲染
form表单如何取消浏览器自动添加的数据校验功能
<form action="" method="post" novalidate>
{# novalidate不做任何校验 #}
{% for form in form_obj %}
<p>{{ form.label }}{{ form }}</p>
{% endfor %}
</form>
<4>.展示提示信息
后端不同请求返回的forms对象一定要是相同的变量名
后端代码
def ab_forms_func(request):
# 1.产生一个空对象
form_obj = MyForm()
if request.method == 'POST':
form_obj = MyForm(request.POST) # request.POST可以看成是一个字典,直接传给forms类校验,字典中无论有多少键值对都没关系,只在乎类中编写的
if form_obj.is_valid(): # 校验数据是否合法
print(form_obj.cleaned_data)
else:
print(form_obj.errors)
# 2.将该对象传递给html文件
return render(request, 'formsPage.html', locals())
前端代码
<form action="" method="post" novalidate>
{% for form in form_obj %}
<p>
{{ form.label }}
{{ form }}
</p>
<span>{{ form.errors.0 }}</span>
{% endfor %}
<input type="sumbit">
</form>
针对错误信息的提示可以修改成各国语言
方式一:自定义内容
给字段对象添加errors_messages参数
username = forms.CharField(min_length=3, max_length=8,label='用户名',
error_messages={
'min_length': '用户名最少三个字符',
'max_length': '用户名最多八个字符',
'required': '用户名不能为空'
}
)
方式二:修改系统语言环境
from django.conf import global_settings
django内部真正的配置文件
我们可以在这里面修改我们想要修改的语言
3.form组件参数
min_length 最小字符
max_length 最大字符
min_value 最小值
max_value 最大值
label 字段注释
error_messages 错误提示
validators 正则校验器
initial 默认值
required 是否必填
widget 控制标签的各项属性
widget = forms.widgets.PasswordInput(attrs={'class': 'form-control', 'username': 'jason'})
三、forms组件校验补充
forms组件针对字段数据的校验,提供了三种类型的校验方式(可以一起使用)
1.直接填写参数
max_length
2.使用正则表达式
from django.core.validators import RegexValidator
class MyForm(Form):
user = fields.CharField(
validators=[
RegexValidator(r'^[0-9]+$', '请输入数字'),
RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
)
3.钩子函数
需求:以后我们写的form组件中写一个注册功能,现在要求判断用户是否已经存在
提供自定义的校验方式
局部钩子:校验单个字段
全局钩子:校验多个字段
<1>.局部钩子
class MyForm(forms.Form):
'''属于第一层校验'''
username = forms.CharField(min_length=3, max_length=8,label='用户名')
password = forms.CharField(min_length=3, max_length=8, label='密码')
confirm_pwd = forms.CharField(min_length=3, max_length=8, label='确认密码')
# 钩子函数>>>:每次只校验一个字段数据
def clean_username(self):
username = self.cleaned_data.get('username')
if username == 'jason':
self.add_error('username', '用户名jason已存在')
return username
<2>.全局钩子
一次可以校验多个字段数据,校验两次密码是否一致
def clean(self):
password = self.cleaned_data.get('password')
confirm_pwd = self.cleaned_data.get('confirm_pwd')
if not password == confirm_pwd:
self.add_error('confirm_pwd', '两次密码不一致')
return self.cleaned_data
四.modelfrom组件
我们学习校验性组件的目的,绝大部分是为了数据录入数据库之前的各项审核
forms组件使用的时候需要对照模型类型编写代码,不够方便
forms组件的强化版本,更好用更简单更方便!!!
from django import forms
from app01 import models
class MyModelForm(forms.ModelForm):
class Meta:
# 写一下要针对那一个表做校验
model = models.UserInfo
# 双下all代表着所有字段
fields = 'all'
labels = {
'username':'用户名'
}
def ab_mf_func(request):
modelform_obj = MyModelForm()
if request.method == 'POST':
modelform_obj = MyModelForm(request.POST,instance=User_obj)
if modelform_obj.is_valid():
modelform_obj.save() # models.UserInfo.objects.create(...)/update(...)
else:
print(modelform_obj.errors)
return render(request, 'modelFormPage.html', locals())