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

 更新时间:2020年7月9日 22:58  点击:3429

最近写的资源策略管理,在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()函数对表单中的数据进行验证操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持猪先飞。

[!--infotagslink--]

相关文章

  • 解决IDEA maven 项目修改代码不生效,mvn clean、install后才生效

    这篇文章主要介绍了解决IDEA maven 项目修改代码不生效,mvn clean、install后才生效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-25
  • IDEA中的clean,清除项目缓存图文教程

    这篇文章主要介绍了IDEA中的clean,清除项目缓存图文教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-25
  • Django def clean()函数对表单中的数据进行验证操作

    这篇文章主要介绍了Django def clean()函数对表单中的数据进行验证操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-09
  • 在Django中使用MQTT的方法

    这篇文章主要介绍了在Django中使用MQTT的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-05-10
  • maven 在执行package,install,deploy时使用clean与不使用clean的不同之处

    有时候用mvn install后,新改的内容不生效,一定要后来使用mvn clean install 才生效,由于之前没有做记录,以及记不清是什么情况下才会出现的问题,于是想看看clean和不clean的区别,感兴趣的朋友跟随小编一起看看吧...2021-08-03
  • 解决导入django_filters不成功问题No module named 'django_filter'

    这篇文章主要介绍了解决导入django_filters不成功问题No module named 'django_filter',具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-15
  • 详解如何使用Docker部署Django+MySQL8开发环境

    这篇文章主要介绍了详解如何使用Docker部署Django+MySQL8开发环境,文中通过示例代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-07-19
  • Django 解决由save方法引发的错误

    这篇文章主要介绍了Django 解决由save方法引发的错误,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-21
  • django数据模型中null和blank的区别说明

    这篇文章主要介绍了django数据模型中null和blank的区别说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-03
  • Django表单外键选项初始化的问题及解决方法

    这篇文章主要介绍了Django表单外键选项初始化的问题及解决方法,需本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,要的朋友可以参考下...2021-04-29
  • Django项目连接MongoDB的三种方法

    本文主要介绍了Django项目连接MongoDB的三种方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-27
  • 使用AJAX和Django获取数据的方法实例

    这篇文章主要给大家介绍了关于使用AJAX和Django获取数据的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-25
  • django前端页面下拉选择框默认值设置方式

    这篇文章主要介绍了django前端页面下拉选择框默认值设置方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-10
  • django ajax发送post请求的两种方法

    这篇文章主要介绍了django ajax发送post请求的两种方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2020-04-30
  • Django开发RESTful API实现增删改查(入门级)

    这篇文章主要介绍了Django开发RESTful API实现增删改查(入门级),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-05-10
  • Django获取model中的字段名和字段的verbose_name方式

    这篇文章主要介绍了Django获取model中的字段名和字段的verbose_name方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-20
  • django中url映射规则和服务端响应顺序的实现

    这篇文章主要介绍了django中url映射规则和服务端响应顺序的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-05-10
  • Django项目如何获得SSL证书与配置HTTPS

    本文总结了如何获得SSL证书并给Django项目配置HTTPS,建议先收藏再阅读,将来有一天你很可能会用到它。...2021-05-01
  • Django后台管理系统的图文使用教学

    在本篇文章里小编给大家整理的是一篇关于Django后台管理系统的图文使用教学内容,需要的朋友们参考下。...2020-04-22
  • 关于C/C++中typedef的定义与用法总结

    在C还是C++代码中,typedef都使用的很多,在C代码中尤其是多,typedef与#define有些相似,其实是不同的,特别是在一些复杂的用法上,需要的朋友可以参考下...2020-04-25