Django【第16篇】:Django之Form组件自定义验证规则
自定义验证规则以及中间件简单介绍
1、python2和python3中的区别

对于python2内置的字符串类型有str和unicode
比如:"abc"是字符串,u"你好"是unicode
字符串(utf-8/gbk编码之后值) unicode
对于python3内置的字符串类型有bytes和unicode
bytes(utf-8/gbk编码之后值) 字符串(unicode) python3 中的bytes,就是python2中的字符串
python2 中的字符串,就是python3中的unicode

2、数据源无法时时更新,有两种方法
方式一:重构构造方法(推荐)

方法一:重构构造方法(推荐)
class ClassesForm(Form):
name = fields.CharField(
required=True, # 必填字段
error_messages={"required": "姓名不能为空!!"}, # 显示中文错误提示
widget=widgets.TextInput(attrs={"placeholder": "姓名", "class": "form-control"}), # 自动生成input框
)
# 如果直接定义成classteacher_id,,_id 的形式,这样你添加数据的时候不会时时更新,所以在下面定义一个重写的方法
# classteacher_id = fields.ChoiceField(choices= models.UserInfo.objects.filter(ut_id = settings.ROLE_CLASSTEACHER).values_list('id', "username")) classteacher_id = fields.ChoiceField(choices=[])
def __init__(self,*args,**kwargs): #重写init方法,时时更新
super().__init__(*args,**kwargs) #继承父类
self.fields["classteacher_id"].choices = models.UserInfo.objects.filter(ut_id = settings.ROLE_CLASSTEACHER).values_list('id', "username")
注意:
要是这样:fields.ChoiceField(choices=[])
注意choices里面传[(1,"讲师"),(2,"班主任"),(3,"管理员")]所以数据库里取的时候得用values_list

方式二:
方法二:ModelChoiceField(不推荐),queryset
from django.forms.models import ModelChoiceField #先导入
class ClassForm(Form):
caption = fields.CharField(error_messages={'required':'班级名称不能为空'})
# headmaster = fields.ChoiceField(choices=[(1,'娜娜',)])
headmaster_id = ModelChoiceField(queryset=models.UserInfo.objects.filter(ut_id=2))
3、Form基本使用

类
字段
is_valid()
cleaned_data
errors
字段参数:
max_length
min_length
validators = [RegexValidators("xxx")] 钩子函数
clean_字段名
注意:
必须有返回值
只能拿自己当前字段值
raise ValidationError("xxx")
下拉框数据源时时更新
1、重写init方法
先执行父类构造方法
self.fields["xx"].choices = xxxxx
2、ModelChoiceField

4、用户登录

- form的字段可以定义正则表达式
password = fields.CharField(
required=True,
min_length=3,
max_length=18,
error_messages={
'required': '密码不能为空',
'min_length': '密码长度不能小于3',
'max_length': '密码长度不能大于18',
'invalid': '密码格式错误',
},
validators=[RegexValidator('\d+','只能是数字') ]
)
注意:error_messages的优先级比validators高

需要导入的模块
from django.forms import Form
from django.forms import fields
from django.forms import widgets
from django.conf import settings
from django.core.validators import ValidationError
from django.core.validators import RegexValidator

class LoginForm(Form):
username = fields.CharField(
required=True, #必填字段
min_length=3,
max_length=16,
error_messages={
"required":"用户名不能为空",
"min_length":"长度不能小于3",
"max_length":"长度不能大于16"
},
widget=widgets.TextInput({"placeholder":"username","class":"form-control"})
)
password = fields.CharField(
required=True,
min_length=3,
max_length=16,
error_messages={
"required": "密码不能为空",
"min_length": "密码长度不能小于3",
"max_length": "密码长度不能大于16",
# "invalid":"密码格式错误"
# error_messages的优先级高,如果写上"invalid":"密码格式错误"这个就会优先显示这个错误
},
widget=widgets.PasswordInput({"placeholder":"password","class":"form-control"}),
validators=[RegexValidator("\d+","密码只能是数字")] #可以进行正则匹配提示错误
) def clean_username(self):
user = self.cleaned_data["username"]
is_exits = models.UserInfo.objects.filter(username=user).count()
if not is_exits:
raise ValidationError("用户名和密码错误")
return user #必须有return

views.py ---------login

def login(request):
if request.method == "GET":
form = LoginForm()
return render(request, "login.html", {"form": form})
else:
form = LoginForm(data=request.POST)
if form.is_valid():
print(form.cleaned_data)
# username = form.cleaned_data["username"]
# password = form.cleaned_data["password"]
# user = models.UserInfo.objects.filter(username=username, password=password).first()
user = models.UserInfo.objects.filter(**form.cleaned_data).first()
if user: #这次是和数据库里的数据进行比较
#验证成功
print(user.username)
request.session[settings.GDP] = {"id":user.id,"username":user.username} #设置session
return redirect("/teacherindex/")
else:
#验证失败,就给增加一个错
form.add_error("password","用户名或密码不正确")
return render(request, "login.html", {"form": form})
else:
return render(request, "login.html", {"form": form})

- 主动向form中添加错误信息
# form.add_error('password','用户名或密码错误')
form.add_error('password',ValidationError('用户名或密码错误'))
这两个都可以,建议用第二个
5、Form扩展(钩子函数)
如果对username做扩展
#先做正则表达式判断
#然后自定义方法验证:也就是clean_xx,称为钩子函数

def clean_username(self):
#可以写自己的验证提示
不像validators只写正则表达式。在这里可以随意写
user=self.clean_data["username"]
is_esits = models.UserInfo.objects.filter(username=user).count()
if not is_esits:
raise validationError("用户名不存在")
return user #必须有返回值
如果 def clean_username(self): 只能取password字段的值
如果 def clean_username(self): 只能取username字段的值
注意:在自己写钩子函数的时候,只能拿自己的字段不能拿别人的
每一种字段就可以用 正则+自定义正则+自定义钩子函数

6、中间件
1、中间件是什么?
中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。
2、做过什么?
用户登录
日志记录
crsf:对所有的post请求做了一个验证
session
权限管理
3、
注意:
对于所有请求的批量做处理的时候用中间件
单独对某几个函数做处理的时候用装饰器
4、使用步骤:

步骤:
1、、先建一个文件夹,里面写一个py文件
2、、然后开始写类
1.中间件就是一个类,类里面写几个方法
class M1(MiddlewareMixin): 必须继承
def process_request(self,request): request:请求里面的所有的东西
print("m1.request_request")
这个方法里面别轻易返回值,要是有返回值就不再继续执行后面的了,执行自己的process_response和上边的response
一般是无返回值的:继续执行后续的中间件和视图函数
def process_response(self,request,response):
return response 2.在settings中的MIDDLEWARE加上路径
文件夹名称.py文件名称.类名
3.找到继承的那个类,吧那个类拿过来
一般不要用导入的方法,不然有时候更新了就没有这个类了,你就把它继承的那个类拿过来,

图示分析过程:
process_reques有返回值:

process_reques无返回值:

在中间件中设置:

示例:

class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__() def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response # 至少要有两个类
class Md1(MiddlewareMixin): #必须继承
def process_request(self,request):
print("md1===process_request")
l = ["/login/"]
#request.path_info:当前的路径
if request.path_info in l: #因为login不做验证,就直接返回none就行了
return None
if not request.session.get(settings.GDP):
return redirect("/login/")
#
# 如果无返回值,就继续执行后续中间件和视图函数
# 如果有返回值,就执行自己的process_response和上面的response
def process_response(self,request,response):
print("md1====process_response1")
return response #必须有返回值 class Md2(MiddlewareMixin):
def process_request(self,request):
print("md2====process_request2")
def process_response(self,request,response):
print("md2====process_response2")
return response

测试:
def testMD(request):
print("view.test")
return HttpResponse("...")
返回结果:

Django【第16篇】:Django之Form组件自定义验证规则的更多相关文章
- 【Django入坑之路】Form组件
1:From组件的简单使用 1创建From: #导入模块 from django import forms from django.forms import fields, widgets # 导入自 ...
- Form组件的验证流程及扩展(钩子)
Form组件的验证流程及扩展(钩子) 常用的form class TestForm(Form): t1 = fields.CharField( widget=widgets.Textarea # 输入 ...
- Django框架第九篇--Django和Ajax、序列化组件(serializers)、自定义分页器、模型表choice参数
Django和Ajax 一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”.即使用Javascript语 ...
- Django多对多关系建立及Form组件
目录 Django多对多关系 1.创建方式一全自动 2.创建方式二纯手撸 3.半自动(推荐使用) forms校验组件 使用forms组件实现注册功能 form常用字段和插件 数据校验 钩子函数 HOO ...
- Python - Django - form 组件自定义校验
reg2.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- Django的form组件——自定义校验函数
from django.shortcuts import render,HttpResponse from django import forms from django.core.exception ...
- Django 模板 语法 变量 过滤器 模板继承 组件 自定义标签和过滤器 静态文件相关
本节目录 一 语法 二 变量 三 过滤器 四 标签Tags 五 模板继承 六 组件 七 自定义标签和过滤器 八 静态文件相关 一 语法 模板渲染的官方文档 关于模板渲染你只需要记两种特殊符号(语法 ...
- form组件的验证
django 的form组件可以实现自定义的验证规则. 创建基于Form的类,在类中创建字段,定义规则. 创建该类的对象,并将待验证的数据传入,使用is_valid()函数. is_valid()函数 ...
- Django之Form自定义验证规则
1.数据源无法时时更新,有两种方法 方式一:重构构造方法(推荐) 方法一:重构构造方法(推荐) class ClassesForm(Form): name = fields.CharField( re ...
随机推荐
- 使用mybatis-generator-core-1.3.2.jar根据数据库表自动生成实体
1 导入mybatis-generator-core-1.3.2.jar 2配置mbg.xml <?xml version="1.0" encoding="UTF- ...
- 一、Robotframework安装步骤
1.安装python并验证安装成功 a.安装python-2.7.14.amd64------默认路径安装即可 b.添加环境变量path:C:\Python27; C:\Python27\Script ...
- serial redirection
int setOption(int fd,int nSpeed, int nBits, char mode,char nEvent, int nStop) { struct termios newti ...
- leetcode 590.N-ary Tree Postorder Traversal N叉树的后序遍历
递归方法 C++代码: /* // Definition for a Node. class Node { public: int val; vector<Node*> children; ...
- 7、Shiro加密和加盐
这里我们以md5加密方法举例,首先我们写一个main方法测试我们的密码经过md5加密之后的得到什么样的字符串: /** * 书写方法测试Md5Hash将密码“houru”加密之后的密文 * 但是仅仅加 ...
- 阶段3 1.Mybatis_02.Mybatis入门案例_3.mybatis注解开发和编写dao实现类的方式
注解的用法 直接创建一个新的项目 下一步直接next 然后finish即可 把之前项目01里面的代码直接复制过来 复制到我们02的注解的工程中 把01项目导入的依赖也都粘贴过来 再把测试类复制过去 复 ...
- 【MM系列】SAP MM模块-分析采购收货完成标识
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP MM模块-分析采购收货完成标 ...
- nginx+memcached缓存图片
1.nginx的配置如下: location ^~ /images/ { set $memcached_key "$uri"; #用URI作为key去memcached中 ...
- .net core 学习小结之 自定义JWT授权
自定义token的验证类 using System; using System.Collections.Generic; using System.IO; using System.Linq; usi ...
- 63 (OC)* NSAutoreleasePool 自动释放池
目录 0:ARC 1: 自动释放池 2:NSAutoreleasePool实现原理 3:autorelease 方法 4: Runloop和Autorelease的关系 5: Using Autore ...