django Form验证

Django之form表单验证顺序

概述

django框架提供了一个forms类,来处理web开发中的表单相关事项。众所周知,form最常作的是对用户输入的内容进行验证,为此django的forms类提供了全面的内容验证支持。html

验证过程

流程详解

  1. 函数full_clean()依次调用每一个field的clean()函数,该函数针对field的max_length,unique等约束进行验证,若是验证成功则返回值,不然抛出ValidationError错误。若是有值返回,则放入form的cleaned_data字典中。
  2. 若是每一个field的内置clean()函数没有抛出ValidationError错误,则调用以clean_开头,以field名字结尾的自定义field验证函数。验证成功和失败的处理方式同步骤1。
  3. 最后,调用form的clean()函数——注意,这里是form的clean(),而不是field的clean()——若是clean没有错误,那么它将返回cleaned_data字典。
  4. 若是到这一步没有ValidationError抛出,那么cleaned_data字典就填满了有效数据。不然cleaned_data不存在,form的另一个字典errors填上验证错误。在template中,每一个field获取本身错误的方式是:{{ form.username.errors }}。
  5. 最后,若是有错误is_valid()返回False,不然返回True。

注意一点:自定义验证机制时:clean()和clean_&()的最后必须返回验证完毕或修改后的值.web

form验证中自定义验证机制

需求

  1. 用户输入的是否为cc,若是是,提示用户
  2. 验证二次输入的密码是否匹配,若是不一致,提示用户

看下views.py中的代码:django

...

from django import forms
from django.core.exceptions import ValidationError
import re


def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    ifnot mobile_re.match(value):
        raise ValidationError('手机号码格式错误')


class LoginForm(forms.Form):
    user = forms.CharField(required=True, error_messages={'required': '用户名不能为空.'})
    pwd = forms.CharField(required=True,
                          min_length=6,
                          max_length=10,
                          error_messages={'required': '密码不能为空.', 'min_length': "至少6位"})

    pwd2 = forms.CharField(required=True,
                          min_length=6,
                          max_length=10,
                          error_messages={'required': '密码不能为空.', 'min_length': "至少6位"})


    num = forms.IntegerField(error_messages={'required': '数字不能空.', 'invalid': '必须输入数字'})

    phone = forms.CharField(validators=[mobile_validate, ], )

    def clean_user(self):
        user = self.cleaned_data.get('user')
        if user == 'cc':
            raise forms.ValidationError('用户名是个人!')

        return user

    def clean(self):
        cleaned_data = self.cleaned_data
        pwd = cleaned_data['pwd']

        pwd2 = cleaned_data['pwd2']
        print(pwd,pwd2)
        if pwd != pwd2:
            raise forms.ValidationError('二次输入密码不匹配')
        return cleaned_data #注意此处必定要return clean_data,不然会报错
  def login(request):
    if request.POST:   objPost = LoginForm(request.POST)    ret = objPost.is_valid() if ret: print(objPost.clean()) else: from django.forms.utils import ErrorDict print(objPost.non_field_errors()) passreturn render(request, 'login.html', {'obj1': objPost}) else: objGet = LoginForm() return render(request, 'login.html', {'obj1': objGet}) ...

HTML 页面中,若是想取clean()报错的信息,因其自己是一个迭代器,因此咱们能够循环返回数据的non_field_errors取值,好比:框架

<div>{%  if obj1.non_field_errors %}{% for item in obj1.non_field_errors %}<spanclass="error_msg">{{ item }}span>{% endfor %}{% endif %}

我来看下html中的设置:函数

<htmllang="en"><head><metacharset="UTF-8"><title>title><style>.error_msg{
            color: red;
        }
    style>head><body><formaction="/login/"method="POST"><div>用户名:
            {{ obj1.user }}{%  if obj1.errors.user %}<spanclass="error_msg">{{ obj1.errors.user.0 }}span>{% endif %}div><div>密码:
            {{ obj1.pwd }}{%  if obj1.errors.pwd %}<spanclass="error_msg">{{ obj1.errors.pwd.0 }}span>{% endif %}div><div>确认密码:
            {{ obj1.pwd2 }}{%  if obj1.errors.pwd2 %}<spanclass="error_msg">{{ obj1.errors.pwd2.0 }}span>{% endif %}div><div>数字:
            {{ obj1.num }}{%  if obj1.errors.num %}<spanclass="error_msg">{{ obj1.errors.num.0 }}span>{% endif %}div><div>电话:
            {{ obj1.phone }}{%  if obj1.errors.phone %}<spanclass="error_msg">{{ obj1.errors.phone.0 }}span>{% endif %}div><div>{%  if obj1.non_field_errors %}{% for item in obj1.non_field_errors %}<spanclass="error_msg">{{ item }}span>{% endfor %}{% endif %}div><inputtype="submit"value="提交"/>form>body>html>
相关文章
相关标签/搜索