Django框架(十五)—— forms组件、局部钩子、全局钩子
forms组件、局部钩子、全局钩子
[TOC]
一、什么是forms组件
forms组件就是一个类,可以检测前端传来的数据,是否合法。
例如,前端传来的邮箱数据,判断邮件格式对不对,用户名中不能以什么开头,等等
二、forms组件的使用
1、使用语法
from django.shortcuts import render, HttpResponse
from django import forms
# 1.先写一个类,继承Form
class MyForm(forms.Form):
# 定义一个属性,可以用来校验字符串类型
# 限制最大长度是8,最小长度是3
name=forms.CharField(max_length=8,min_length=3)
pwd=forms.CharField(max_length=8,min_length=3,required=True)
# 校验是否是邮箱格式
email=forms.EmailField()
# 2.在视图函数中使用MyForm来校验数据
# 实例化产生对象,传入要校验的数据(可以传字典字典,也可以不传)
myform=MyForm(request.POST)
# 3.校验,is_valid如果是true表示校验成功(满足myform里的条件),反之,校验失败
if myform.is_valid():
# myform.clean_data 表示校验通过的数据
print(myform.cleaned_data)
return HttpResponse('校验成功')
else:
print(myform.cleaned_data)
#校验失败的信息,myform.errors 可以当成一个字典,它是所有错误信息{name:[列表,]}
# 每个字段.errors 是一个列表,表示每个字段的错误信息
print(myform.errors)
return HttpResponse('校验失败')
方法总结:
- myform.clean_data 验证通过的数据
- myform.errors 错误数据的对象
- myform.errors.as_data 错误数据的信息
2、组件的参数
max_length # 代表该字段最长为多少
min_length # 代表该字段最短为多少
error_messages # 这是设置错误信息的属性
required # 默认值为True,意思是你传来的字段必须有它,没有的话校验失败
widget=widgets.TextInput() # 你在模板渲染的时候,就会渲染成Input框,type为text
lable # lable='用户名'
# 例子
pwd = forms.CharField(max_length=8, min_length=3, required=True, label='密码',
error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'},
3、注意点
- MyForm实例化时,传入必须是字典,或者不传
- errors 调用这个方法,返回值是对象,你可以通过get取值
- 要校验的数据,字段可以多于MyForm类中的字段,但不能少,少相当于该字段没有数据
三、渲染模板
# form组件可以在视图函数中使用,也可以在模板中使用
# 视图层:
def index(request):
myform = Myform()
return render(request,'index.html',local())
# 模板层
# 1.渲染方式一:
<form action='' method='post'>
用户名:{{myform:name}} <br>
<input type='submit' value = '提交'></input>
</form>
# 这里的{{myform:name}} 和你写input框是一样的效果,就是属性比input框多一点
# 2.渲染方式二(推荐使用):
<form action='' method='post'>
{% for foo in myform%}
{{ foo.lable }} : {{ foo }} <br>
<input type='submit' value = '提交'></input>
</form>
# 页面显示都是一样的,foo.lable不是用户名,是name,但是可以在创建Myform类时,在CharFiel中添加lable='用户名',这样就行了。
# 3.渲染方式三:
<form action='' method='post'>
{{ myform.as_p }}
<input type='submit' value = '提交'></input>
</form>
四、渲染错误信息
<form action='' method='post'>
{% for foo in myform%}
{{ foo.lable }} : {{ foo }} <span>{{foo.errors.0}}</span><br>
<input type='submit' value = '提交'></input>
</form>
五、局部钩子
1、什么是局部钩子
定义一个函数,名字叫:clean_字段名字,内部,取出该字段,进行校验,如果通过,将该字段返回,如果失败,抛异常(ValidationError)
2、定义局部钩子
# 函数名:clean_字段名字
def clean_name(self):
# self:当前form对象
name = self.cleaned_data.get('name')
if name.startswith('sb'):
# 失败,抛异常,将异常信息以 {'name':value} 写入errors字典中
raise ValidationError('不能以sb开头')
# 正常,把name返回到clean_data,将name写入clean_data字典中
return name
注意点:
- 校验失败,抛异常,将异常信息以 {'name':value} 写入 errors 字典中
- 校验成功,把name返回到clean_data,写入clean_data字典中
- 抛出异常的类型为ValidationError,
from django.core.exceptions import ValidationError导入
六、全局钩子
1、什么是全局钩子
在写注册用户的时候,有输入密码,确认密码,可以进行布局钩子处理,处理完毕是不是在进行判断,判断他们是否相等,相等的话,就存到数据库中,不相等就抛个异常。
2、定义全局钩子
# 重写clean方法
def clean(self):
# 程序能走到该函数,前面校验已经通过了,所以可以从cleaned_data中取出密码和确认密码
pwd=self.cleaned_data.get('pwd')
re_pwd=self.cleaned_data.get('re_pwd')
# 进行自己的校验
if pwd==re_pwd:
# 通过,直接返回cleaned_data
return self.cleaned_data
else:
# 失败,抛异常(ValidationError)
raise ValidationError('两次密码不一致')
全局钩子注意点:
- 校验失败,抛异常,将异常信息以
{'__all__':[value,]}写入 errors 字典中 - 校验成功,返回clean_data字典
- 抛出异常的类型为ValidationError,
from django.core.exceptions import ValidationError导入
钩子错误信息渲染注意点:
局部钩子抛出的异常会添加到该字段中的错误信息中,获取错误信息:
前台:
for循环生成input框,{{ foo.errors.0 }}全局钩子抛出的异常会添加到_all_中,获取错误信息:
后台:
myforms.errors.get('__all__')[0]注意先判断myforms.errors.get('__all__')是否存在
前台:{{ myforms.errors.__all__.0 }}如果程序走到了局部钩子这一步,说明传的字典里的数据符合要求,此时就可以从clean_data中取数据,因为此时clean_data中的数据全符合要求,而且clean_data是一个字典
局部钩子,全局钩子所抛出异常的类型为ValidationError,以下导入
from django.core.exceptions import ValidationError
七、完整的forms组件校验
1、视图层
from django.shortcuts import render, HttpResponse, redirect
# forms组件数据校验的功能
# 第一步:先要继承Form
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
# 写一个类
class MyForm(forms.Form):
# 定义一个属性,可以用来校验字符串类型
# 限制最大长度是8,最小长度是3
name = forms.CharField(max_length=8, min_length=3, label='用户名'
error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'},
widget=widgets.TextInput(attrs={'class': 'form-control'}))
pwd = forms.CharField(max_length=8, min_length=3, required=True, label='密码',
error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'},
widget=widgets.PasswordInput())
re_pwd = forms.CharField(max_length=8, min_length=3, required=True, label='确认密码',
error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填'},
widget=widgets.PasswordInput())
# 校验是否是邮箱格式
email = forms.EmailField(label='邮箱', error_messages={'required': '这个必须填', 'invalid': '不符合邮箱格式'})
# aa = forms.CharField(label='选择', error_messages={'required': '这个必须填', 'invalid': '不符合邮箱格式'},widget=widgets.CheckboxInput())
def clean_name(self):
# self:当前form对象
name = self.cleaned_data.get('name')
if name.startswith('sb'):
# 失败,抛异常
raise ValidationError('不能以傻逼开头')
# 正常,把name返回
return name
def clean(self):
pwd = self.cleaned_data.get('pwd')
re_pwd = self.cleaned_data.get('re_pwd')
if pwd == re_pwd:
return self.cleaned_data
else:
raise ValidationError('两次密码不一致')
def index_form(request):
# 生成对象时(实例化),需要传入要校验的数据(字典)
if request.method == 'GET':
myform = MyForm()
return render(request,'indxe2.html',locals())
elif request.method == 'POST':
myform = MyForm(request.POST)
if myform.is_valid():
# print(myform.cleaned_data) # 验证通过的数据
# models.User.objects.create(name='lqz',pwd='123',re_pwd='123)
myform.cleaned_data.pop('re_pwd')
models.User.objects.create(**myform.cleaned_data)
return redirect('http://www.baidu.com')
else:
all_error = myform.errors.get('__all__')
if all_error:
all_error = all_error[0]
# print(myform.errors.as_data)
return render(request, 'indxe3.html', locals())
2、模板层
<form action="" method="post" novalidate>
{% for foo in myform %}
<p>{{ foo.label }}:{{ foo }} <span>{{ foo.errors.0 }}</span></p>
{% endfor %}
<input type="submit" value="提交"><span>{{ all_error }}</span>
</form>
注意点:
局部钩子的错误信息:
前台:
for循环生成input框,{{ foo.errors.0 }}全局钩子的错误信息:
后台:
myforms.errors.get('__all__')[0]注意先判断myforms.errors.get('__all__')是否存在
前台:{{ myforms.errors.__all__.0 }}校验全部通过,创建数据时,从
clean_data中获取数据,但是必须要将其中多于的数据pop掉,如clean_data.pop('r_pwd')
Django框架(十五)—— forms组件、局部钩子、全局钩子的更多相关文章
- Django学习之八:forms组件【对form舒心了】
目录 Django forms组件 bound and unbound form instance forms渲染有关 隐藏一个字段,不渲染它 form 校验 form类 ModelForm 利用Mo ...
- Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程
一.序列化类的增.删.改.查 用drf的序列化组件 -定义一个类继承class BookSerializer(serializers.Serializer): -写字段,如果不指定source ...
- Bootstrap入门(十五)组件9:面板组件
Bootstrap入门(十五)组件9:面板组件 虽然不总是必须,但是某些时候你可能需要将某些 DOM 内容放到一个盒子里.对于这种情况,可以试试面板组件. 1.基本实例 2.带标题的面板 3.情景效果 ...
- Django框架基础之Form组件
服务端假设所有用户提交的数据都是不可信任的,所以Django框架内置了form组件来验证用户提交的信息 form组件的2大功能: 1 验证(显示错误信息) 2 保留用户上次输入 ...
- Django(十五)Form组件
参考博客: https://www.cnblogs.com/haiyan123/p/7778888.html http://www.cnblogs.com/wupeiqi/articles/61441 ...
- Django框架(五)
九.Django与Ajax 一.Ajax简介 AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语 ...
- django框架中的form组件的用法
form组件的使用 先导入: from django.forms import Form from django.forms import fields from django.forms impor ...
- Django(十五)模板详解:模板标签、过滤器、模板注释、模板继承、html转义
一.模板的基础配置及使用 [参考]https://docs.djangoproject.com/zh-hans/3.0/topics/templates/ 作为Web框架,Django提供了模板,用于 ...
- Vue(十五)组件
一. 组件component 1. 什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码 组件是自定义元素(对象) 2. 定义组件 ...
- salesforce lightning零基础学习(十五) 公用组件之 获取表字段的Picklist(多语言)
此篇参考:salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type) 我们在lightning中在前台会经常碰到获取pi ...
随机推荐
- VC6.0在Win8,10下的兼容性调整
Microsoft Visual C++ 6.0,简称VC6.0,是微软推出的一款C++编译器,将“高级语言”翻译为“机器语言(低级语言)”的程 序.Visual C++是一个功能强大的可视化软件开发 ...
- Python面试题之如何用Python来发送邮件?
python实现发送和接收邮件功能主要用到poplib和smtplib模块. poplib用于接收邮件,而smtplib负责发送邮件. 代码如下: 1 #! /usr/bin/env python 2 ...
- Python爬虫抓取 python tutorial中文版,保存为word
看到了中文版的python tutorial,发现是网页版的,刚好最近在学习爬虫,想着不如抓取到本地 首先是网页的内容 查看网页源码后发现可以使用BeautifulSoup来获取文档的标题和内容,并保 ...
- tomcat脚本
!/bin/sh # eg: tomcat.sh start xxx # proc_dir="/usr/local/xxx/tomcat-zc-web/bin" proc_name ...
- 十万级百万级数据量的Excel文件导入并写入数据库
一.需求分析 最近接到一个需求,导入十万级,甚至可能百万数据量的记录了车辆黑名单的Excel文件,借此机会分析下编码过程; 首先将这个需求拆解,发现有三个比较复杂的问题: 问题一:Excel文件导入后 ...
- Rxjava Retrofix2 okhttp3网络框架自解(转)
直接代码 类一 public class Okhttp3Utils { private static OkHttpClient mOkHttpClient; public static OkHttpC ...
- 最大流的SAP算法模板
明天补充~~~先上代码 #include<iostream> #include<string> #include<queue> #include<vector ...
- java的BigDecimal比较大小
java的BigDecimal比较大小 //前提为a.b均不能为null if(a.compareTo(b) == -1){ System.out.println("a小于b"); ...
- testNG之顺序执行
@Test testNG1.java: import org.testng.annotations.Test; public class testNG1 { @Test public void t ...
- jdbc 可处理数据库事物的通用增删查改函数
首先弄清四种隔离级别的和三种数据并发 之间的关系 通用查询函数 //使用PreparedStatement实现对不同表的通用的返回一个对象的查询操作 //使用泛型机制,参数里先传入一个类的类型 pub ...