1、数据源无法时时更新,有两种方法

方式一:重构构造方法(推荐)

方法一:重构构造方法(推荐)
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))

2、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

3、用户登录

- 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('用户名或密码错误'))
  这两个都可以,建议用第二个

4、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_password(self): 只能取password字段的值
如果 def clean_username(self): 只能取username字段的值
注意:在自己写钩子函数的时候,只能拿自己的字段不能拿别人的
每一种字段就可以用 正则+自定义正则+自定义钩子函数 # 注意:
  clean_xx(self):pass 局部钩子函数
  clean(self):pass    全局钩子函数 例子:

1、局部钩子函数

 def clean_username(self):
username = self.cleaned_data.get("username")
valid = models.UserInfo.objects.filter(username = username).first()
if valid:
raise ValidationError("用户名已存在")
return username

2、全局钩子函数

#自定义全局钩子:验证两次密码是否一致
def clean(self):
if self.cleaned_data.get("password") == self.cleaned_data.get("password_again"):
return self.cleaned_data
else:
raise ValidationError("两次密码不一致")

Django之Form自定义验证规则的更多相关文章

  1. Django【第16篇】:Django之Form组件自定义验证规则

    自定义验证规则以及中间件简单介绍 1.python2和python3中的区别 对于python2内置的字符串类型有str和unicode 比如:"abc"是字符串,u"你 ...

  2. yii2中自定义验证规则rules

    作者:白狼 出处:www.manks.top/article/yii2_custom_rules 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追 ...

  3. yii2中的rules 自定义验证规则详解

    yii2的一个强大之处之一就是他的Form组件,既方便又安全.有些小伙伴感觉用yii一段时间了,好嘛,除了比tp"难懂"好像啥都没有. 领导安排搞一个注册的功能,这家伙刷刷刷的又是 ...

  4. validatebox自定义验证规则以及使用

    //===============jsp======state==== //开启验证 <script  type="text/javascript"> ​​​​​​​y ...

  5. Jquery Validate自定义验证规则,一个汉字等于两个字符长度

    使用Jquery validate时写的一些东西,在这里做个笔记 在使用 Jquery validate 的minlength和maxlength进行文本框内容长度验证的时候,对于一个汉字的长度检测结 ...

  6. easyui的validatebox重写自定义验证规则的几个实例

    validatebox已经实现的几个规则: 验证规则是根据使用需求和验证类型属性来定义的,这些规则已经实现(easyui API): email:匹配E-Mail的正则表达式规则. url:匹配URL ...

  7. thinkPHP5.0验证器自定义验证规则

    自定义验证规则 protected $rule = [ 'views' => 'require|number|checkviews:0',//checkviews为自定义验证规则,0是传过去的规 ...

  8. Jquery Validate 相关参数及常用的自定义验证规则

    一.官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation 二.默认校验规则 1 2 3 4 5 6 7 8 9 10 1 ...

  9. YII开发技巧分享——模型(models)中rules自定义验证规则

    YII的models中的rules部分是一些表单的验证规则,对于表单验证十分有用,在相应的视图(views)里面添加了表单,在表单被提交之前程序都会自动先来这里面的规则里验证,只有通过对其有效的限制规 ...

随机推荐

  1. python类初探

    class human: is_alive=True is_man=True def __init__(self,age): print('this is __init__() method, whi ...

  2. 在node.js中建立你的第一个HTTp服务器

    这一章节我们将从初学者的角度介绍如何建立一个简单的node.js HTTP 服务器 创建myFirstHTTPServer.js //Lets require/import the HTTP modu ...

  3. 剑指OFFER18 判断一个二叉树的子树

    public class a18_IsSubTree { public static boolean hasSubTree(TreeNode treeRoot1, TreeNode treeRoot2 ...

  4. linux ssh 命令使用解析

    前一阵远程维护Linux服务器,使用的是SSH,传说中的secure shell. 登陆:ssh [hostname] -u user 输入密码:***** 登 陆以后就可以像控制自己的机器一样控制它 ...

  5. Linux网络编程 gethostbyaddr()

    C语言函数 概述: 返回对应于给定地址的主机信息. #include <winsock.h> struct hostent FAR *PASCAL FAR gethostbyaddr(co ...

  6. c ++ auto 的使用

    该文转自:https://www.cnblogs.com/KunLunSu/p/7861330.html C++98 auto 早在C++98标准中就存在了auto关键字,那时的auto用于声明变量为 ...

  7. BZOJ_3165_[Heoi2013]Segment_线段树

    BZOJ_3165_[Heoi2013]Segment_线段树 Description 要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第i条被插入的线段的标号为i. 2.给定一个数 ...

  8. ACM学习历程—HDU1716 排列2(dfs && set容器)

    Description Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数.   Input 每组数据占一行,代表四张卡片上的数字( ...

  9. ESFramework Demo -- P2P通信Demo(附源码)

    现在我们将在ESFramework Demo -- 文件传送Demo 的基础上,使用ESPlus提供的第四个武器,为其增加P2P通信的功能.在阅读本文之前,请务必先掌握ESFramework 开发手册 ...

  10. Spring 3.1新特性之三:Spring对声明式缓存的支持

    一.概述: Spring 3.1 引入了激动人心的基于注释(annotation)的缓存(cache)技术,它本质上不是一个具体的缓存实现方案(例如EHCache 或者 OSCache),而是一个对缓 ...