一、什么是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导入

钩子错误信息渲染注意点:

局部钩子抛出的异常会添加到该字段中的错误信息中,获取错误信息:

前台: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组件、局部钩子、全局钩子的更多相关文章

  1. Django学习之八:forms组件【对form舒心了】

    目录 Django forms组件 bound and unbound form instance forms渲染有关 隐藏一个字段,不渲染它 form 校验 form类 ModelForm 利用Mo ...

  2. Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程

    一.序列化类的增.删.改.查 用drf的序列化组件   -定义一个类继承class BookSerializer(serializers.Serializer):   -写字段,如果不指定source ...

  3. Bootstrap入门(十四)组件8:媒体对象

    Bootstrap入门(十四)组件8:媒体对象 这是一个抽象的样式,用以构建不同类型的组件,这些组件都具有在文本内容的左或右侧对齐的图片(就像博客评论或 Twitter 消息等). 1.基本样式 2. ...

  4. “全栈2019”Java第九十四章:局部内部类详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. Django框架基础之Form组件

    服务端假设所有用户提交的数据都是不可信任的,所以Django框架内置了form组件来验证用户提交的信息 form组件的2大功能:       1 验证(显示错误信息)       2 保留用户上次输入 ...

  6. Django(十四)课程机构列表页数据展示,Django的modelform,关于urls的重新分发

    关于urls的重新分发: 如果所有url都配置在根路径的urls.py里,会特别多,而且也不易于修改,Django框架里支持urls的重新分发: 1.在根路径的urls配置上: PS:namespac ...

  7. django框架中的form组件的用法

    form组件的使用 先导入: from django.forms import Form from django.forms import fields from django.forms impor ...

  8. Django 框架篇(四) : 视图(view)详解 以及 路由系统(url)

    |--Django的View(视图) |-- CBV和FBV: |-- 给视图增加装饰器: |-- request对象: |-- response对象: |-- Django的路由系统(url): | ...

  9. Django框架(四)-- 路由控制:有名/无名分组、反向解析、路由分发、名称空间、伪静态、APPEND_SLASH、不同版本的Django区别、Django虚拟环境搭建

    路由控制 一.简单路由配置 url(r'^booklist$', views.booklist) 第一个参数是正则表达式,第二个参数是视图函数 每个正则表达式前面的'r' 是可选的但是建议加上.它告诉 ...

  10. How tomcat works 读书笔记十四 服务器组件和服务组件

    之前的项目还是有些问题的,例如 1 只能有一个连接器,只能处理http请求,无法添加另外一个连接器用来处理https. 2 对容器的关闭只能是粗暴的关闭Bootstrap. 服务器组件 org.apa ...

随机推荐

  1. 0629 Flink Meetup 北京站 PPT下载

    工程实用问题解决方案介绍,实用

  2. angularjs 运行时报错ERROR in node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected. node_modules/rxjs/internal/types.d.ts(81,74): error TS1005: ';' expected. node_modules/rxjs/internal/t

    解决方法: 在package.json文件里面 修改 "rxjs": "^6.0.0" 为 "rxjs": "6.0.0" ...

  3. SQL基础知识整理

    建议:关键字和函数名全部大写:数据库名称.表名称.字段名称全部小写:分号结尾.但是大小写语句不区分,本人讨厌大写(英语菜,不能一眼看出内容),所以全部小写.[]看情况可有可无,{}花括号的内容必须要有 ...

  4. [CODEVS4632][BZOJ4326]运输计划

    题目描述 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P ...

  5. flask回顾

    pip install flask from flask import Flask app = Flask(__name__) # 命令行启动,用manager,访问会变的非常慢 pip instal ...

  6. <binary search> 154 162

    154. Find Minimum in Rotated Sorted Array II 当数组中存在大量的重复数字时,就会破坏二分查找法的机制,将无法取得 O(lgn) 的时间复杂度,又将会回到简单 ...

  7. vscode用服务打开html

    ①安装插件 此时右击会有: ②anywhere

  8. Codeforces Round #549 (Div. 2) D 数学

    https://codeforces.com/contest/1143/problem/D 题意 有nk个城市,第1,k+1,2k+1,...,(n-1)k+1城市有餐厅,你每次能走l距离,a为起始位 ...

  9. c++基础第一篇

    前言:我是从c和c++对比的角度来讲解c++的基础知识. (1)c++格式如下: #include <iostream> //标准输入输出头文件 using namespace std; ...

  10. springcloud2.x之management.security.enabled=false报错处理

    1. springcloud1.5.x的消息总线配置是 # RabbitMq的地址.端口,用户名.密码 spring.rabbitmq.host=localhost spring.rabbitmq.p ...