forms组件
内容概要
- forms组件渲染标签
- forms组件展示信息
- forms组件校验补充
- forms组件参数补充
- forms组件源码剖析
- modelform组件
- django中间件
forms组件渲染标签
后端
class MyForm(forms.Form):
username = forms.CharField(min_length=2, max_length=8)
age = forms.IntegerField(min_value=0, max_value=200)
email = forms.EmailField()
def ad_index_func(request):
form_obj = MyForm()
return render(request, 'indexPage.html', locals())
{# 方式一#}
<p>{{ form_obj.as_p }}</p>
{{ form_obj.as_table }}
<p></p>
{{ form_obj.as_ul }}
优势 :全自动 简单粗暴
劣势:封装程度太高了 扩展性差 主要用于测试
{#方式二#}
{{ form_obj.username.label }}
{{ form_obj.username }}
{{ form_obj.age.label }}
{{ form_obj.age }}
{{ form_obj.email.label }}
{{ form_obj.email }}
优势:扩展性强,
劣势:太繁琐了
{#方式三#}
{% for foo in form_obj %}
{{ foo.label }}
{{ foo }}
{% endfor %}
封装程度较高 扩展性高 编写简单 推荐使用
注意事项
forms组件只负责渲染获取用户数据的便签 也就意味着form标签与按钮都需要自己写
<form action="" method="post">
{% for foo in form_obj %}
<p>{{ foo.label }}
{{ foo }}</p>
{% endfor %}
<input type="submit" name="" id="">
</form>
前端校验是弱不禁风的 最终都需要后端来校验所以我们在使用forms组件的时候可以直接取消前端帮我们的校验
<form novalidate></form>
forms组件展示信息
后端不同请求返回的forms
对象一定要是相同的变量名
<form action="" method="post" novalidate>
{% for foo in form_obj %}
<p>{{ foo.label }}
{{ foo }}
{{ foo.errors.0 }}</p>
{% endfor %}
<input type="submit" name="" id="">
</form>
def ad_index_func(request):
# 产生一个空对象
form_obj = MyForm()
if request.method == "POST":
# request.POST 可以看成一个字典
# 所以可以把这个 request.POST直接放到 forms产生的类里面
form_obj = MyForm(request.POST)
return render(request, 'indexPage.html', locals())
针对错误的提示信息可以修改为各国语言
方式1 自定义内容
给字段对象添加errors_messages
参数
username = forms.CharField(min_length=2, max_length=8,
error_messages={'min_length': '最少为两个字符',
'max_length': '最多为八个字符',
'required': '用户输入不能为空'}) # 为空的报错
方式2:修改系统语言环境
这个global_settings
是我们配置文件settings
它爹
forms组件校验补充
forms组件针对字段数据的校验 提供了三种类型的校验方式(三种可以一起使用)
第一种类型:直接写参数
max_length
第二种类型:使用正则表达式
validators
from django.core.validators import RegexValidator
user = forms.CharField(
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
)
第三种类型: 钩子函数
编写代码
自定义校验规则
局部函数
class MyForm(forms.Form):
from django.core.validators import RegexValidator
user = forms.CharField(min_length=2, max_length=8)
age = forms.IntegerField(min_value=0, max_value=200, label='年龄')
email = forms.EmailField(label='邮箱')
# 钩子函数>>>:校验的最后一个环 是在字段所有的校验参数之后触发
# 局部钩子>>>:每次只校验一个字段数据校验用户名是否存在
def clean_user(self):
# 获取前端的 user 传过来的数据
user = self.cleaned_data.get('user')
# 进行比对 如果是 jason # 钩子函数>>>:校验的最后一个环 是在字段所有的校验参数之后触发
def clean_user(self):
# 获取前端的 user 传过来的数据
user = self.cleaned_data.get('user')
# 进行比对 如果是 jason
if user == 'jason':
# 就添加一个给 errors的字典里 'user': '用户吗jason已存在'
#
self.add_error('user', '用户名jason已存在')
return user
if user == 'jason':
# 就添加一个 'user': '用户吗jason已存在'
self.add_error('user', '用户名jason已存在')
return user
全局钩子
# 全局钩子:一次可以校验多个字段数据 校验两次密码是否一致
def clean(self):
password = self.cleaned_data.get('password')
re_pass = self.cleaned_data.get('re_pass')
if not password == re_pass:
self.add_error('re_pass', '两次密码不一致')
return self.cleaned_data
记得勾出来什么就得 返回什么
全局钩子是把全部的数据都钩出来,不管你用不用你都得把数据全部返回出去
forms组件参数补充
min_length 最小字符
max_length 最大字符
min_value 最小值
max_value 最大值
label 字段注释
error_messages 错误提示
validators 正则校验器
initial 默认值
required 是否必填
widget 控制标签的各项属性
widget
用法
from django.forms import widgets
password = forms.IntegerField(label='密码',
widget=forms.PasswordInput(attrs={'class': 'form_control'}))
forms组件源码剖析
切入口是: form_obj.is_valid()
先看 self.is_bound
是什么玩意
去看看 self._errors
去看看 self.full_clean
做了什么事
这三个函数
这是第一个
我们去看第二个
第三个
medelform组件
"""
我们学习校验组件的目的 绝大部分是为了数据录入数据库之前的各项审核
forms组件使用的时候需要对照模型类编写代码 不够方便
"""
forms组件的强化版本 更好用更简单更方便
models 层
class UserInfo(models.Model):
username = models.CharField(max_length=32, verbose_name='用户名')
age = models.IntegerField(verbose_name='年龄')
view
from django import forms
from app01 import models
class MyModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = '__all__'
labels = {'username': '用户名'}
def ad_index_func(request):
modelform_obj = MyModelForm()
if request.method == 'POST':
modelform_obj = MyModelForm(request.POST)
if modelform_obj.is_valid():
"""
这个save 就相当于 models.UserInfo.objects.create()
或
models.UserInfo.objects.update()
"""
modelform_obj.save()
else:
print(modelform_obj.errors)
return render(request, 'indexPage.html', locals())
<form action="" method="post" novalidate>
{% for foo in modelform_obj %}
<p>{{ foo.label }}
{{ foo }}
{{ foo.errors.0 }}</p>
{% endfor %}
<input type="submit" name="" id="">
</form>
会把 表中的字段自动创建出来