Django def clean()函数对表单中的数据进行验证操作


Posted in Python onJuly 09, 2020

最近写的资源策略管理,在ceilometer 中创建alarm时,name要求是不能重复的,所以在创建policy的时候,要对policy的name字段进行验证,而django中正好拥有强大的表单数据验证的功能。

#这是policy中的name字段,在表单的数据进行提交的时候,所有的数据流会经过clean()这个函数

name = forms.CharField(max_length=255, label=_("Name"))

#在clean函数中先取出表单中的name字段,在从数据库里面拿到所有的数据进行检查

  def clean(self):
    cleaned_data = super(CreatePolicyForm, self).clean()
    name = cleaned_data.get('name')

    try:
      policys = api.nova.policy_list(self.request)
    except:
      exceptions.handle(request,
               _('Unable to retrieve policys list.'))
    if policys is not None and name is not None:
      for policy in policys:
        if policy.name.lower() == name.lower():
          raise forms.ValidationError(
            _('The name "%s" is already used by another policy.')
            % name
          )
    return cleaned_data

补充知识:django中关于表单自定义验证器和常用验证器

常用验证器:

在验证某个字段的时候,可以传递一个 validators 参数用来指定验证器,进一步对数据进行过滤。验证器有很多,但是很多验证器我们其实已经通过这个 Field 或者一些参数就可以指定了。比如 EmailValidator ,我们可以通过 EmailField 来指定,比如 MaxValueValidator ,我们可以通过 max_value 参数来指定。

以下是一些常用的验证器:

1. MaxValueValidator :验证最大值。

2. MinValueValidator :验证最小值。

3. MinLengthValidator :验证最小长度。

4. MaxLengthValidator :验证最大长度。

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

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

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

器: RegexValidator 。比如现在要验证手机号码是否合格,那么我们可以通过以下代码实

现:

class MyForm(forms.Form):

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

自定义验证:

有时候对一个字段验证,不是一个长度,一个正则表达式能够写清楚的,还需要一些其他复杂的逻辑,那么我们可以对某个字段,进行自定义的验证。比如在注册的表单验证中,我们想要验证手机号码是否已经被注册过了,那么这时候就需要在数据库中进行判断才知道。对某个字段进行自定义的验证方式是,定义一个方法,这个方法的名字定义规则是: clean_fieldname 。如果验证失败,那么就抛出一个验证错误。比如要验证用户表中手机号码之前是否在数据库中存在,那么可以通过以下代码实现:

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

def clean_telephone(self):


telephone = self.cleaned_data.get('telephone')


exists = User.objects.filter(telephone=telephone).exists()


if exists:



raise forms.ValidationError("手机号码已经存在!")


else:



return telephone

以上是对某个字段进行验证,如果验证数据的时候,需要针对多个字段进行验证,那么可以重写 clean 方法。比如要在注册的时候,要判断提交的两个密码是否相等。那么可以使用以下代码来完成:

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

pwd1 = forms.CharField(max_length=12)

pwd2 = forms.CharField(max_length=12)

def clean(self):


cleaned_data = super().clean()


pwd1 = cleaned_data.get('pwd1')


pwd2 = cleaned_data.get('pwd2')


if pwd1 != pwd2:



raise forms.ValidationError('两个密码不一致!')

提取错误信息:

如果验证失败了,那么有一些错误信息是我们需要传给前端的。这时候我们可以通过以下属性来获取:

1. form.errors :这个属性获取的错误信息是一个包含了 html 标签的错误信息。

2. form.errors.get_json_data() :这个方法获取到的是一个字典类型的错误信息。将某个字段的名字作为 key ,错误信息作为值的一个字典。

3. form.as_json() :这个方法是将 form.get_json_data() 返回的字典 dump 成 json 格式的字符串,方便进行传输。

4. 上述方法获取的字段的错误值,都是一个比较复杂的数据。比如以下:

{'username': [{'message': 'Enter a valid URL.', 'code': 'invalid'}, {'message': 'Ensurethis value has at most 4 characters (it has 22).', 'code': 'max_length'}]}

那么如果我只想把错误信息放在一个列表中,而不要再放在一个字典中。这时候我们可以定义一个方法,把这个数据重新整理一份。实例代码如下:

class MyForm(forms.Form):
username = forms.URLField(max_length=4)

def get_errors(self):


errors = self.errors.get_json_data()


new_errors = {}


for key,message_dicts in errors.items():



messages = []



for message in message_dicts:




messages.append(message['message'])



new_errors[key] = messages


return new_errors

这样就可以把某个字段所有的错误信息直接放在这个列表中。

以上这篇Django def clean()函数对表单中的数据进行验证操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python通过自定义isnumber函数判断字符串是否为数字的方法
Apr 23 Python
Python中强大的命令行库click入门教程
Dec 26 Python
使用Python处理Excel表格的简单方法
Jun 07 Python
浅谈Python爬虫基本套路
Mar 25 Python
详解Python:面向对象编程
Apr 10 Python
pip 安装库比较慢的解决方法(国内镜像)
Oct 06 Python
Python有参函数使用代码实例
Jan 06 Python
基于SpringBoot构造器注入循环依赖及解决方式
Apr 26 Python
python实现简单猜单词游戏
Dec 24 Python
利用python+request通过接口实现人员通行记录上传功能
Jan 13 Python
Python列表的深复制和浅复制示例详解
Feb 12 Python
Python GUI编程之tkinter 关于 ttkbootstrap 的使用详解
Mar 03 Python
django form和field具体方法和属性说明
Jul 09 #Python
浅谈Python里面None True False之间的区别
Jul 09 #Python
Django中Q查询及Q()对象 F查询及F()对象用法
Jul 09 #Python
在CentOS7下安装Python3教程解析
Jul 09 #Python
django 将自带的数据库sqlite3改成mysql实例
Jul 09 #Python
Python使用xlrd实现读取合并单元格
Jul 09 #Python
django ObjectDoesNotExist 和 DoesNotExist的用法
Jul 09 #Python
You might like
DISCUZ 论坛管理员密码忘记的解决方法
2009/05/14 PHP
php实现的仿阿里巴巴实现同类产品翻页
2009/12/11 PHP
Laravel 微信小程序后端实现用户登录的示例代码
2019/11/26 PHP
javawscript 三级菜单的实现原理
2009/07/01 Javascript
JavaScript 计算图片加载数量的代码
2011/01/01 Javascript
javascript实现图片切换的幻灯片效果源代码
2012/12/12 Javascript
Js 回车换行处理的办法及replace方法应用
2013/01/24 Javascript
js生成验证码并直接在前端判断
2015/05/15 Javascript
Javascript验证方法大全
2015/09/21 Javascript
js判断手机访问或者PC的几个例子(常用于手机跳转)
2015/12/15 Javascript
深入学习JavaScript的AngularJS框架中指令的使用方法
2016/03/05 Javascript
使用jQuery实现WordPress中的Ctrl+Enter和@评论回复
2016/05/21 Javascript
浅谈jquery.form.js的ajaxSubmit和ajaxForm的使用
2016/09/09 Javascript
工作中常用的js、jquery自定义扩展函数代码片段汇总
2016/12/22 Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
2017/01/16 Javascript
bootstrap3使用bootstrap datetimepicker日期插件
2017/05/24 Javascript
微信小程序图片选择区域裁剪实现方法
2017/12/02 Javascript
Vue中使用Sortable的示例代码
2018/04/07 Javascript
解决Vue中mounted钩子函数获取节点高度出错问题
2018/05/18 Javascript
vue下history模式刷新后404错误解决方法
2018/08/18 Javascript
详解webpack编译速度提升之DllPlugin
2019/02/05 Javascript
layui 对弹窗 form表单赋值的实现方法
2019/09/04 Javascript
vue 封装 Adminlte3组件的实现
2020/03/18 Javascript
[03:37]2014DOTA2国际邀请赛 主赛事第一日胜者组TOPPLAY
2014/07/19 DOTA
qpython3 读取安卓lastpass Cookies
2016/06/19 Python
浅谈Python 对象内存占用
2016/07/15 Python
Python Numpy 数组的初始化和基本操作
2018/03/13 Python
解决python nohup linux 后台运行输出的问题
2018/05/11 Python
python中for循环输出列表索引与对应的值方法
2018/11/07 Python
Python中整数的缓存机制讲解
2019/02/16 Python
解决TensorFlow模型恢复报错的问题
2020/02/06 Python
Python使用扩展库pywin32实现批量文档打印实例
2020/04/09 Python
计算机应用专业毕业生求职信
2014/06/03 职场文书
基于flask实现五子棋小游戏
2021/05/25 Python
redis数据结构之压缩列表
2022/03/21 Redis
MongoDB修改oplog大小的四种方法
2022/04/11 MongoDB