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实现2014火车票查询代码分享
Jan 10 Python
python在命令行下使用google翻译(带语音)
Jan 16 Python
python实现绘制树枝简单示例
Jul 24 Python
简述Python中的面向对象编程的概念
Apr 27 Python
python3+PyQt5实现自定义流体混合窗口部件
Apr 24 Python
python面试题之列表声明实例分析
Jul 08 Python
Python 过滤错误log并导出的实例
Dec 26 Python
pycharm的python_stubs问题
Apr 08 Python
浅谈keras.callbacks设置模型保存策略
Jun 18 Python
python3中TQDM库安装及使用详解
Nov 18 Python
python中zip()函数遍历多个列表方法
Feb 18 Python
python实现求纯色彩图像的边框
Apr 08 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
十天学会php之第六天
2006/10/09 PHP
收集的PHP中与数组相关的函数
2007/03/22 PHP
深入for,while,foreach遍历时间比较的详解
2013/06/08 PHP
php实现把数组按指定的个数分隔
2014/02/17 PHP
PHP构造函数与析构函数用法示例
2016/09/28 PHP
ext for eclipse插件安装方法
2008/04/27 Javascript
JavaScript基本概念初级讲解论坛贴的学习记录
2009/02/22 Javascript
js 实现无缝滚动 兼容IE和FF
2009/07/15 Javascript
javascript appendChild,innerHTML,join性能比较代码
2009/08/29 Javascript
JS 获取滚动条高度示例代码
2013/10/24 Javascript
js定时器的使用(实例讲解)
2014/01/06 Javascript
jQuery基于当前元素进行下一步的遍历
2014/05/20 Javascript
jquery获取form表单input元素值的简单实例
2016/05/30 Javascript
js实现统计字符串中特定字符出现个数的方法
2016/08/02 Javascript
详解webpack性能优化——DLL
2017/10/20 Javascript
vue项目中应用ueditor自定义上传按钮功能
2018/04/27 Javascript
浅谈Angularjs中不同类型的双向数据绑定
2018/07/16 Javascript
详解微信小程序与内嵌网页交互实现支付功能
2018/10/22 Javascript
原生js实现each方法实例代码详解
2019/05/27 Javascript
React 全自动数据表格组件——BodeGrid的实现思路
2019/06/12 Javascript
详解nuxt 微信公众号支付遇到的问题与解决
2019/08/26 Javascript
layui表格分页 记录勾选的实例
2019/09/02 Javascript
[02:43]2014DOTA2国际邀请赛 官方Alliance战队纪录片
2014/07/14 DOTA
[02:17]《辉夜杯》TRG战队巡礼
2015/10/26 DOTA
Python导出数据到Excel可读取的CSV文件的方法
2015/05/12 Python
使用pandas对两个dataframe进行join的实例
2018/06/08 Python
Python3按一定数据位数格式处理bin文件的方法
2019/01/24 Python
Python 图像处理: 生成二维高斯分布蒙版的实例
2019/07/04 Python
python pyecharts 实现一个文件绘制多张图
2020/05/13 Python
css3动画事件—webkitAnimationEnd与计时器time事件
2013/01/31 HTML / CSS
巴西体育用品商店:Lojão dos Esportes
2018/07/21 全球购物
印尼购物网站:iLOTTE
2019/10/16 全球购物
诉讼代理人授权委托书
2014/04/08 职场文书
《最大的麦穗》教学反思
2014/04/17 职场文书
教你如何使用Python开发一个钉钉群应答机器人
2021/06/21 Python
windows server2012 R2下安装PaddleOCR服务的的详细步骤
2022/09/23 Servers