Django form组件 - 神奇的后端直接渲染HTML

 前言

之前在HTML页面中利用form表单向后端提交数据时会写一些获取用户输入的标签并且使用form标签将其包裹起来。并且很多场景下都需要对用户的输入做校验,比如用户输入的长度和格式等,如果用户输入的有误就需要在页面上相应的位置显示相应的错误信息。而django form组件实现了上面所述的功能。

form组件功能

总结起来,django from组件的主要功能有以下三点:

①生成页面可用的HTML标签;

②对用户提交的数据进行校验;

③保留上次输入的内容。

form组件基本使用

form组件的使用和django模型非常类似,现在应用下的views.py中定义好form类,代码如下:

# views.py
from django import forms
class MyForm(forms.Form):'''# username字符串类型最小3位最大8位# password字符串类型最小3位最大8位# email字段必须符合邮箱格式  xxx@xx.com# label属性用来指定字段展示信息'''# username字符串类型,最小3位,最大8位username = forms.CharField(max_length=8,min_length=3, lable='用户名')# password,字符串类型,最小3位,最大8位password = forms.CharField(max_length=8,min_length=3, lable='密码')# email字段必须符合邮箱格式email = forms.EmailField(lable='邮箱')

测试form组件的环境也有两种方式,一种方式同样是通过test.py,另一种方式就是通过pycharm的测试环境Python console,这里采用第二种方式进行测试。

# 1 导入需要测试的文件
from first import views# 2 将需要校验的数据组织成字典的形式传入自定义的form类进行校验
form_obj = views.MyForm({'username':'python',,'emali':'123'})# 3 判断数据是否合法:注意该方法只有在所有的数据全部合法的情况下才会返回True
form_obj.is_valid()  # False# 4 查看所有通过校验的数据
form_obj.cleaned_data  # {'username': 'python', }# 5 查看所有不符合校验规则的字段和不符合原因,错误原因是列表,因为可能错误原因有多个
form_obj.errors  # {'email': ['Enter a valid email address.']}# 6 如果校验数据中出现了类中没有的字段,forms组件只会校验存在的字段,不存在的字段传了直接忽略
form_obj = views.MyForm({'username':'python',,'emali':'123@qq.com','hobby':'read'})
form_obj.is_valid()  # True# 7 默认情况下,类里面所有的字段都必须传值,也就意味着校验数据的时候,默认情况下数据可以多传但是不能少传
form_obj = views.MyForm({'username':'jason',})
form_obj.is_valid()  # False

form组件的校验规则可以总结出以下方法:

给MyForm传值实例化对象,传值方式:将带校验的字段和数据组织成字典的形式
is_valid()		该方法只有在所有的数据全部合法的情况下才会返回True
cleaned_data	查看所有校验通过的数据
errors			查看所有不符合校验规则以及不符合的原因,{key: ['']}
has_error()		判断某一个字段是否不合法,不合法返回True校验数据只校验类中出现的字段,多传不影响,多传的字段直接忽略
校验数据 默认情况下 类里面所有的字段都必须传值,即少传肯定不合法

form组件渲染标签

上面提到form组件可以自动帮忙渲染获取用户输入的标签(input select radio checkbox),但是不能自动渲染提交按钮,那么是如何实现的呢?首先是后端的代码,在views.py中书写视图函数:

# views.py
def index(request):# 先产生一个空对象form_obj = MyForm()if request.method == 'POST':# 获取用户数据进行校验,如果一条一条的获取用户数据太过繁琐,而且校验数据需要字典格式,而request.POST获取到的数据格式就是queryset——dict对象form_obj = MyForm(request.POST)# 如果数据合法应该操作数据库,这里先简写if form_obj.is_valid():return HttpResponse('OK')# 如果是get请求返回直接将空对象传递给html页面return render(request,'register.html',locals())

如果数据不合法需要将错误信息展示到前端,那么如何将错误信息展示到前端呢?因为form校验产生的错误信息就是字典格式,到前端就是自定义对象,所以可以通过前端点点点的方式,下面是前端register.html页面

<body>
<form action="" method="post" novalidate>  <!--novalidate参数阻止浏览器自动校验-->{% for form in form_obj %}<p>{{ form.label }} : {{ form }}<!--span是预留的展示错误信息的标签,form.errors.0的意思是只展示第一条错误提示,否则forms组件会将错误信息展示成无序列表的形式--><span style="color: red">{{ form.errors.0 }}</span></p>{% endfor %}<input type="submit">
</form>
</form>
</body>

错误信息在前端显示都是英文的,能不能改成中文的呢?可以通过参数error_messages来自定制错误信息。

class MyForm(forms.Form):'''error_messages参数需要构造成字典的数据结构,key是校验条件,value是校验失败时的提示信息'''username = forms.CharField(min_length=5,max_length=12,label='用户名',error_messages={'min_length': '用户名不能少于5位','max_length': '用户名不能超多12位','required': '用户名不能为空',})password = forms.CharField(min_length=6, max_length=12, label='密码')re_password = forms.CharField(min_length=6, max_length=12, label='确认密码')email = forms.EmailField(label='邮箱')

HOOK钩子函数

上述form组件的基本使用只是对数据的第一层校验,很多时候对参数还需要一些特殊的校验规则,这时候就可以使用钩子函数,钩子函数在form组件中类似于第二道校验,能够让我们自定义校验规则,校验流程通过第一层校验之后就会来到钩子函数,可以在钩子函数中进一步定制校验规则,钩子函数分为两种分别是局部钩子和全局钩子,钩子函数定义在form类中。

局部钩子

当需要给单个字段增加校验规则的时候就可以使用局部钩子了。比如规定用户名中不能包含hook

# views.py
class MyForm(forms.Form):username = forms.CharField(min_length=5,max_length=12,label='用户名',error_messages={'min_length':'用户名不能少于5位','max_length':'用户名不能超多12位','required':'用户名不能为空',})def clean_username(self):username = self.cleaned_data.get('username')if '666' in username:self.add_error('username', '中包含了hook')return username

定义局部钩子函数可以总结为以下几点:

①局部钩子的函数名为:clean_字段(),字段就是自定义校验规则的字段;

②该方法中在cleaned_data中获取该字段的数据,局部钩子中只能拿到当前字段的数据;

③校验数据失败时,通过add_error方法给字段添加错误信息;

④局部钩子取出的字段数据一定要返回出去。

全局钩子

当需要给多个字段增加校验规则的时候可以使用全局钩子。比如校验两次密码输入是否一致:

# views.py
class MyForm(forms.Form):password = forms.CharField(min_length=6, max_length=12, label='密码')re_password = forms.CharField(min_length=6, max_length=12, label='确认密码')def clean(self):password = self.cleaned_data.get('password')re_password = self.cleaned_data.get('re_password')if password != re_password:self.add_error('re_password', '两次密码输入不一致')return self.cleaned_data

定义全局钩子函数可以总结为以下几点:

①全局钩子可以在cleaned_data内获得任意字段的数据;

②全局钩子取出的cleaned_data一定要返回出去。

form组件参数介绍

首先是常用参数:

min_length			最少几位字符
max_length			最多几位字符
label				字段名
required  			控制字段是否必填(默认required=True)
error_messages  	自定义报错信息,字典的结构
initial  			初始值,input框里面的初始值value

HTML页面上的标签可以修改属性,那么form组件是直接渲染的,如何修改标签的属性呢?就是通过widget参数,通过该参数可以修改标签的属性。

class MyForm(forms.Form):username = forms.CharField(min_length=5,max_length=12,widget=forms.widgets.TextInput(attrs={'class': 'form-control'}))"""
总结:
widget=forms.widgets.TextInput()默认是TextInput(及input[type='text'])
widget=forms.widgets.PasswordInput()密码格式
widget=forms.widgets.EmailInput()邮箱格式attrs提供字段的属性,可以是内置的也可以是自定义的;如有多个class:空格隔开即可。
"""

另外在第一道校验规则中,还支持正则校验,就是通过validators参数进行正则校验:

from django import forms
from django.core.validators import RegexValidatorclass MyForm(forms.Form):phone = forms.CharField(label='手机号',validators=[RegexValidator(r'^[0-9]+$', '请输入数字'),RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],)"""
总结:
validators的值是一个列表,烈面可以更多个正则表校验条件
RegexValidator第一个参数是正则表校验条件,第二个是校验失败是的提示信息"""

form组件其他标签渲染

form组件不止能对input框进行渲染,也支持对radio select checkbox标签进行渲染:

# radio单选
gender = forms.ChoiceField(choices=((1, "男"), (2, "女"), (3, "保密")),label="性别",initial=1,widget=forms.widgets.RadioSelect()
)# checkbox多选
hobby = forms.MultipleChoiceField(choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),label="爱好",initial=[1, 3],widget=forms.widgets.CheckboxSelectMultiple()
)# 下拉单选:即使添加attrs={'multiple': 'multiple'}任然为单选
hobby2 = forms.ChoiceField(choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),label="爱好",initial=3,widget=forms.widgets.Select()
)# 下拉多选
hobby3 = forms.MultipleChoiceField(choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),label="爱好2",initial=[1, 3],widget=forms.widgets.SelectMultiple()
)# 选择checkbox是否选择, initial空表示False, 只要有值就是True默认选中(任何值都可以)
keep = forms.ChoiceField(choices=(('False', 0), ('True', 1)),label="是否记住密码",initial='',widget=forms.widgets.CheckboxInput()
)

在使用choice参数时如果choices展示的数据是动态从数据库中获取的,还需要额外的设置:

class BookAddForm(forms.Form):name = forms.CharField(label='图书名称',error_messages={'required': '图书名称不能为空'},widget=forms.widgets.TextInput())price = forms.DecimalField(label='价格',error_messages={'required': '图书价格不能为空'},widget=forms.widgets.TextInput())publish_date = forms.DateField(label='出版日期',error_messages={'required': '出版日期不能为空'},widget=forms.widgets.DateInput())publish_id = forms.ChoiceField(label='出版社',error_messages={'required':'出版社不能为空'},widget=forms.widgets.Select())author = forms.MultipleChoiceField(label='作者',error_messages={'required':'作者不能为空'},widget=forms.widgets.SelectMultiple())def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# choices字段的数据动态来自数据库self.fields['publish_id'].choices = models.Publish.objects.values_list('pk', 'name')self.fields['author'].choices = models.Author.objects.values_list('pk', 'name')

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/469197.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rust基础拾遗--进阶

Rust基础拾遗 前言1.结构体1.1 具名字段型结构体1.2 元组型结构体1.3 单元型结构体1.4 结构体布局1.5 用impl定义方法1.5.1 以Box、Rc或Arc形式传入self1.5.2 类型关联函数 1.6 关联常量1.7 泛型结构体1.8 带生命周期参数的泛型结构体1.9 带常量参数的泛型结构体1.10 让结构体类…

vscode 提取扩展时出错。XHR failed

检查 vscode 设置中的代理服务器&#xff0c;位置如下图 清空 vocode 中的 Proxy&#xff0c;我黄线框的部分&#xff0c;内容清空。 检查电脑系统环境变量&#xff0c;是否设置了 http_proxy 和 https_proxy&#xff0c;如果有设置&#xff0c;则删除这两项&#xff0c;下载完…

MySQL 基础知识(六)之数据查询(一)

目录 1 基本查询 1.1 查询相关列 (select * / 列名) 1.2 别名 (as) 1.3 去重 (distinct) 1.4 对列中的数据进行运算 (、-、*、/) 2 条件查询 (where) 2.1 等值查询 () 2.2 非等值查询 (>、<、>、<、!、><) 2.3 逻辑判断 (and、or、not) 2.4 区间判…

IDEA中mybatis配置文件表名显示红色,提示 Unable to resolve table ‘xxx‘

问题&#xff1a;IDEA中mybatis配置文件表名显示红色&#xff0c;提示 Unable to resolve table ‘xxx’ 解决方法&#xff1a; 使用快捷提示键 Alt Enter&#xff0c;选择 Go to SQL Resolution Scopes&#xff08;转到SQL的解析范围&#xff09;

HarmonyOS鸿蒙学习基础篇 - Column/Row 组件

前言 Row和Column组件是线性布局容器&#xff0c;用于按照垂直或水平方向排列子组件。Row表示沿水平方向布局的容器&#xff0c;而Column表示沿垂直方向布局的容器。这些容器具有许多属性和方法&#xff0c;可以方便地管理子组件的位置、大小、间距和对齐方式。例如&#xff0c…

洛谷_P1059 [NOIP2006 普及组] 明明的随机数_python写法

这道题的关键在于去重和排序&#xff0c;去重可以联想到集合&#xff0c;那排序直接使用sort方法。 n int(input()) data set(map(int,input().split( ))) data list(data) data.sort() print(len(data)) for i in data:print(i,end )

ClickHouse--08--SQL DDL 操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 SQL DDL 操作1 创建库2 查看数据库3 删除库4 创建表5 查看表6 查看表的定义7 查看表的字段8 删除表9 修改表9.1 添加列9.2 删除列9.3 清空列9.4 给列修改注释9.5 修…

基于LightGBM的回归任务案例

在本文中&#xff0c;我们将学习先进的机器学习模型之一&#xff1a;Lightgbm。在对XGB模型进行了越来越多的改进以获得更好的性能之后&#xff0c;XGBoost是一种极限梯度提升机器&#xff0c;但通过lightgbm&#xff0c;我们可以在没有太多计算的情况下实现类似或更好的结果&a…

STM32—DHT11温湿度传感器

文章目录 一.温湿度原理1.1 时序图 二.代码 一.温湿度原理 1.1 时序图 (1).下图一是DHT11总的时序图。 (2).图二对应图一的左边黑色部分&#xff0c;图三对应图一的绿色部分&#xff0c;图四的左部分图对应图一的红色部分&#xff0c;图四的右部分对应图一的黄色部分。 (3)…

【深蓝学院】移动机器人运动规划--第4章 动力学约束下的运动规划--作业

文章目录 1. T11.1 题目1.2 求解1.3 Pontryagin Minimum Principle 的拓展 2. T22.1 题目2.2 求解 3. Reference 1. T1 1.1 题目 1.2 求解 1.3 Pontryagin Minimum Principle 的拓展 2. T2 2.1 题目 2.2 求解 Listing1&#xff1a; demo_node.cpp/trajectoryLibrary() for(i…

中小学信息学奥赛CSP-J认证 CCF非专业级别软件能力认证-入门组初赛模拟题第二套(阅读程序题)

CSP-J入门组初赛模拟题二 二、阅读程序题 (程序输入不超过数组或字符串定义的范围&#xff0c;判断题正确填√错误填X;除特殊说明外&#xff0c;判断题 1.5分&#xff0c;选择题3分&#xff0c;共计40分) 第一题 1 #include<bits/stdc.h> 2 using namespace std; 3 i…

AI换脸离线本地版-讲解2

嘿&#xff0c;准备好了吗&#xff1f;我来给你幽默地讲解下AI换脸&#xff01; 所谓AI换脸&#xff0c;就是让你变成“百变小萝莉”或者“花心大少爷”一样&#xff0c;只需一键操作&#xff0c;就能把你的脸魔法般地贴到别人脸上&#xff0c;就像是面部贴纸一样。你可以秒变…