django Model层常用验证器及自定义验证器详解


Posted in Python onJuly 15, 2020

在Django中,对数据进行校验有两种方式:一种是通过Form校验,一种是通过Model校验。在此,我对Model中的校验方法做下记录。

示例之前补充以下几点:

1、Django数据校验方式分为以下三步:

Model.clean_fields() 验证字段基本规则比如长度格式等;

Model.clean() 可自定义验证条件和报错信息;

Model.validate_unique() 为验证添加的唯一性约束。

2、此三步验证通过调用full_claen(exclude=None, validate_unique=True)来依次执行。

exclude:可以用来指定不需要执行校验的field。ModelForm也利用这个参数来将field排除。

validate_unique:用来指定是否需要执行Model.validate_unique()。

3、而full_clean()又是通过调用is_valid()方法来执行。

4、save()执行的时候是不会自动调用full_clean()来进行校验的。

校验应该在save()执行之前完成,你可以先在form进行校验,也可以在model中进行校验。但是,你必须确保通过这两个校验之后的数据是绝对没有问题的“干净”数据,然后再调用save()方法将数据存储入库。

5、校验中的错误处理

我们使用ValidationError来在Model.clean中抛出错误,这个错误信息将会存储在以NON_FIELD_ERRORS为key的字典中。这个key是用来存储对于整个model中的错误信息的。

如何获取校验的错误信息:

from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
try:
  article.full_clean()
except ValidationError as e:
  non_field_errors = e.message_dict[NON_FIELD_ERRORS]

如何指定对于某个特定的field的校验错误信息:

class Article(models.Model):
  ...
  def clean(self):
    if self.status == 'draft' and self.pub_date is not None:
      # raise ValidationError({'pub_date': _('Draft entries may not have a publication date.')})
      raise ValidationError({'pub_date': 'Draft entries may not have a publication date.'})
    ...

如何指定多个field的校验错误信息:

class Article(models.Model):
  ...
  def clean(self):
    if self.status == 'draft' and self.pub_date is not None:
      raise ValidationError({'pub_date': 'Draft entries may not have a publication date.', 
                 'creator': 'Creator can't be null'})
    ...

如何指定全局性校验错误信息:

class Article(models.Model):
  ...
  def clean(self):
    if self.status == 'draft' and self.pub_date is not None:
      raise ValidationError('Draft entries may not have a publication date.')
    ...

进入正题:

一、如何使用验证器:

在验证某个字段的时候,在模型或者自定义form表单中传递一个 validators 参数用来指定验证器,进一步对数据进行过滤。

或者,通过model中的 Field类型 或者一些参数就可以指定。

比如 EmailValidator ,我们可以通过 指定字段类型为EmailField 来指定。

比如 MaxValueValidator ,我们可以通过 max_value 、max_length参数来指定。

class Interview(models.Model):
  feedback = models.TextField(max_length=1024, validators=[MinLengthValidator(20, message='不少于20字')], verbose_name='面试反馈')
  mail = models.EmailField(max_length=64, blank=True, null=True, verbose_name='邮箱')
  age= models.IntegerField(max_value=64, blank=True, null=True, verbose_name='年龄')

二、常用自带验证器:

1. MaxValueValidator :验证最大值。

2. MinValueValidator :验证最小值。

3. MinLengthValidator :验证最小长度。

4. MaxLengthValidator :验证最大长度。

5. EmailValidator :验证是否是邮箱格式。

6. URLValidator :验证是否是 URL 格式。

7. RegexValidator :如果还需要更加复杂的验证,那么我们可以通过正则表达式的验证。

class Demo(models.Model):
telephone = models.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='请输入正确格式的手机号码!')])

三、自定义验证器:

方法:

如果你想要自定义model的校验,或者想要修改model的属性的话,就要重写clean()方法。

class Interview(models.Model):
  feedback = models.TextField(max_length=1024, validators=[MinLengthValidator(20, message='不少于20字')], verbose_name='面试反馈')
  mail = models.EmailField(max_length=64, blank=True, null=True, verbose_name='邮箱')
  age= models.IntegerField(max_value=64, blank=True, null=True, verbose_name='年龄'
  ...
 
  def clean(self):
    if self.result_1 == InterviewResult.FAIL and len(self.feedback) < 20:
      raise ValidationError({'feedback': '不少于20字'})

效果:

django Model层常用验证器及自定义验证器详解

django Model层常用验证器及自定义验证器详解

如果你想做一个全局性的错误提示,可以这样:

...
  def clean(self):
    if self.result_1 == InterviewResult.FAIL and len(self.feedback) < 20:
      raise ValidationError('不少于20字吧')

效果:

django Model层常用验证器及自定义验证器详解

以上这篇django Model层常用验证器及自定义验证器详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之大话题小函数(1)
Oct 10 Python
python脚本设置系统时间的两种方法
Feb 21 Python
python字典多键值及重复键值的使用方法(详解)
Oct 31 Python
wxpython实现图书管理系统
Mar 12 Python
利用Pandas 创建空的DataFrame方法
Apr 08 Python
使用python根据端口号关闭进程的方法
Nov 06 Python
python库matplotlib绘制坐标图
Oct 18 Python
python列表切片和嵌套列表取值操作详解
Feb 27 Python
Windows下pycharm安装第三方库失败(通用解决方案)
Sep 17 Python
pycharm 多行批量缩进和反向缩进快捷键介绍
Jan 15 Python
python 获取域名到期时间的方法步骤
Feb 10 Python
如何用python绘制雷达图
Apr 24 Python
浅谈Django前端后端值传递问题
Jul 15 #Python
浅谈python出错时traceback的解读
Jul 15 #Python
Django视图、传参和forms验证操作
Jul 15 #Python
一文解决django 2.2与mysql兼容性问题
Jul 15 #Python
django 模型字段设置默认值代码
Jul 15 #Python
django序列化时使用外键的真实值操作
Jul 15 #Python
Django:使用filter的pk进行多值查询操作
Jul 15 #Python
You might like
JAVA/JSP学习系列之七
2006/10/09 PHP
php中配置文件操作 如config.php文件的读取修改等操作
2012/07/07 PHP
php ctype函数中文翻译和示例
2014/03/21 PHP
异步加载技术实现当滚动条到最底部的瀑布流效果
2014/09/16 PHP
PHP实现一个简单url路由功能实例
2016/11/05 PHP
CodeIgniter框架验证码类库文件与用法示例
2017/03/18 PHP
php readfile()修改文件上传大小设置
2017/08/11 PHP
TP5(thinkPHP框架)实现后台清除缓存功能示例
2019/05/29 PHP
php curl发送请求实例方法
2019/08/01 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
js电信网通双线自动选择技巧
2008/11/18 Javascript
自动最大化窗口的Javascript代码
2013/05/22 Javascript
js jquery获取随机生成id的服务器控件的三种方法
2013/07/11 Javascript
node.js中的buffer.toJSON方法使用说明
2014/12/14 Javascript
js简单获取表单中单选按钮值的方法
2016/08/23 Javascript
BootStrap实现带有增删改查功能的表格(DEMO详解)
2016/10/26 Javascript
js实现下一页页码效果
2017/03/07 Javascript
vue图片加载与显示默认图片实例代码
2017/03/16 Javascript
ng-alain表单使用方式详解
2018/07/10 Javascript
JS/jQuery实现简单的开关灯效果【案例】
2019/02/19 jQuery
Python书单 不将就
2017/07/11 Python
Python基于回溯法子集树模板解决野人与传教士问题示例
2017/09/11 Python
详解python while 函数及while和for的区别
2018/09/07 Python
Pycharm无法使用已经安装Selenium的解决方法
2018/10/13 Python
python for和else语句趣谈
2019/07/02 Python
为什么从Python 3.6开始字典有序并效率更高
2019/07/15 Python
python打印9宫格、25宫格等奇数格 满足横竖斜相加和相等
2019/07/19 Python
python 发送json数据操作实例分析
2019/10/15 Python
构造器Constructor是否可被override?
2013/08/06 面试题
.NET面试问题集
2015/12/08 面试题
介绍一下Linux内核的排队自旋锁
2014/08/27 面试题
面包店的创业计划书范文
2014/01/16 职场文书
少先队入队活动方案
2014/02/08 职场文书
篮球社团活动总结
2014/06/27 职场文书
个人剖析材料范文
2014/09/30 职场文书
Redis主从复制操作和配置详情
2022/09/23 Redis