首页 > python web

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

时间:2020-07-09 python web 查看: 960

最近写的资源策略管理,在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博客。

展开全文
上一篇:django form和field具体方法和属性说明
下一篇:解决更改AUTH_USER_MODEL后出现的问题
输入字:
相关知识
django学习之ajax post传参的2种格式实例

AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新,下面这篇文章主要给大家介绍了关于django学习之ajax post传参的2种格式的相关资料,需要的朋友可以参考下

Python djanjo之csrf防跨站攻击实验过程

csrf攻击,即cross site request forgery跨站(域名)请求伪造,这里的forgery就是伪造的意思。这篇文章主要给大家介绍了关于Python djanjo之csrf防跨站攻击的相关资料,需要的朋友可以参考下

django admin实现动态多选框表单的示例代码

借助django-admin,可以快速得到CRUD界面,但若需要创建多选标签字段时,需要对表单进行调整,本文通过示例代码给大家介绍django admin多选框表单的实现方法,感兴趣的朋友跟随小编一起看看吧

Flask登录注册项目的简单实现

一个简单的用户注册和登录的页面,涉及到验证,数据库存储等等,本文主要介绍了Flask登录注册项目的简单实现,从目录结构开始,感兴趣的可以了解一下