django之form表单验证

Posted lshedward

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django之form表单验证相关的知识,希望对你有一定的参考价值。

form组件的校验功能

 views.py

from django.shortcuts import render, HttpResponse

# Create your views here.

from django import forms
from django.forms import widgets

class UserForm(forms.Form):
    name = forms.CharField(min_length=4,label=用户名) # 必须用required
    pwd = forms.CharField(min_length=4,label=密码)
    r_pwd = forms.CharField(min_length=4,label=确认密码)
    email = forms.EmailField(label=邮箱)
    tel = forms.CharField(label=手机)


def reg(request):
    if request.method == POST:

        # form = UserForm({‘name‘: ‘ed‘, ‘email‘: ‘[email protected]‘})  # 加多少个键值都无所谓,只要能匹配全Form里的字段就会返回True
        # print(form.is_valid())  # 返回布尔值
        

        form = UserForm(request.POST)  # form表单的name属性值应该与forms组件字段名称一致

        if form.is_valid():
            print(form.changed_data)  # 存的是通过校验的字典
        else:
            print(form.cleaned_data)  # {正确的键值,"email":"[email protected]"}
            print(form.errors)  # {"name":["insure this value has at least 4 characters]}

            print(type(form.errors))  # ErrorDict
            print(form.errors.get(name))
            print(type(form.errors.get(name)))  # ErrorList
            print(form.errors.get(name)[0])  # This field is required.
        ‘‘‘
        if 所有字段校验成功,则form.cleaned_data:{‘name‘: ‘edward‘, ‘email‘: ‘[email protected]‘}

        ‘‘‘
        return render(request, register.html, locals())

    form = UserForm()   # get请求的form,渲染form组件用
    return render(request, register.html, locals())

 

html

<form action="" method="post">
    {% csrf_token %}
    <p>用户名:<input type="text" name="user"></p>
    <p>密码:<input type="password" name="pwd"></p>
    <p>确认密码:<input type="password" name="r_pwd"></p>
    <p>邮箱:<input type="email" name="email"></p>
    <p>手机号:<input type="text" name="tel"></p>
    <input type="submit" value="提交">
</form>

 

form组件渲染的三种方式

<h3>form组件渲染方式1</h3>

<form action="" method="post">
    {% csrf_token %}
    <p>{{ form.name.label }}:{{ form.name }} <span>{{ form.name.errors.0 }}</span></p>
    <p>{{ form.pwd.label }}:{{ form.pwd }} <span>{{ form.pwd.errors.0 }}</span></p>
    <p>{{ form.r_pwd.label }}:{{ form.r_pwd }} <span>{{ form.r_pwd.errors.0 }}</span></p>
    <p>{{ form.email.label }}:{{ form.email }} <span>{{ form.email.errors.0 }}</span></p>
    <p>{{ form.tel.label }}:{{ form.tel }} <span>{{ form.tel.errors.0 }}</span></p>
    <input type="submit" value="提交">
</form>


<hr>
<h3>form组件渲染方式2</h3>
<form action="" method="post">
    {% csrf_token %}

    {% for filed in form %}
        <p>
            <label for="">{{ filed.label }}</label>
            {{ filed }}
        </p>

    {% endfor %}


    <input type="submit" value="提交">
</form>

<hr>
<h3>form组件渲染方式3 --- 不建议使用这种方式,因为它只能固定放那么几个标签,缺乏灵活性,以后改动麻烦</h3>

<form action="" method="post">
    {% csrf_token %}

    {{ form.as_p }}

    <input type="submit" value="提交">
</form>

 

显示错误信息和参数配置

class UserForm(forms.Form):
    name = forms.CharField(min_length=4, label=用户名,
                           error_messages={"required": "该字段不能为空"},
                           widget=widgets.TextInput(attrs={class: form-control})
                           )  # 必须用要提示错误信息的关键词
    pwd = forms.CharField(min_length=4, label=密码,
                          widget=widgets.PasswordInput(attrs={class: form-control}),
                          error_messages={
                              "required": "该字段不能为空"
                          })
    r_pwd = forms.CharField(min_length=4, label=确认密码,
                            error_messages={"required": "该字段不能为空"},
                            widget=widgets.PasswordInput(attrs={class: form-control}),
                            )
    email = forms.EmailField(label=邮箱,
                             error_messages={"required": "该字段不能为空", invalid: "格式错误"},
                             widget=widgets.TextInput(attrs={class: form-control}),
                             )
    tel = forms.CharField(label=手机,
                          error_messages={"required": "该字段不能为空", },
                          widget=widgets.TextInput(attrs={class: form-control}),
                          )

 

局部钩子

 def clean_name(self):
        val = self.cleaned_data.get(name)

        ret = UserInfo.objects.filter(name=val)

        if not ret:
            return val
        else:
            raise ValidationError(该用户已注册!)
            
            
 def clean_tel(self):
    val = self.cleaned_data.get(tel)
    ret = UserInfo.objects.filter(tel=val)

    if len(ret) == 11:
        return val
    else:
        raise ValidationError(手机号格式错误)
            
# 源码
def _clean_fields(self):
    try:
        if isinstance(field, FileField):
            initial = self.get_initial_for_field(field, name)
            value = field.clean(value, initial)
        else:
            value = field.clean(value)
        self.cleaned_data[name] = value
        if hasattr(self, clean_%s % name):
            value = getattr(self, clean_%s % name)()
            self.cleaned_data[name] = value
     except ValidationError as e :
        self.add_error(name, e)

 

全局钩子

为了解耦,新建一个myforms.py的文件,把有关forms的代码都放在这里面。

# 全局钩子

# 走完所有的校验才走clean
def clean(self):
    # 走完所有的校验才走clean
    pwd = self.cleaned_data.get(pwd)
    r_pwd = self.cleaned_data.get(r_pwd)
    
    # 都满足不低于4个字符这个条件后才验证密码是否一致
    if pwd and r_pwd:
        if pwd == r_pwd:
            return self.cleaned_data
        else:
            raise ValidationError(两次密码不一致)

            else:
                return self.cleaned_data
        
#源码
def clean(self):
    """
    Hook for doing any extra form-wide cleaning after Field.clean() has been
    called on every field. Any ValidationError raised by this method will
    not be associated with a particular field; it will have a special-case
    association with the field named ‘__all__‘.
    """
    return self.cleaned_data

def _clean_form(self):
    try:
        cleaned_data = self.clean()
    except ValidationError as e:
        self.add_error(None, e)
    else:
        if cleaned_data is not None:
            self.cleaned_data = cleaned_data
            
            
# 全局钩子在前端没有显示,要在处理post请求的代码里给错误信息一个变量并传到前端
errors = form.errors.get(__all__)

# 当两次密码不一致时,在前端显示这个错误
<p>
    {{ form.r_pwd.label }}:{{ form.r_pwd }}
    <span class="pull-right error">{{ form.r_pwd.errors.0 }}</span>
    <span class="pull-right error">{{ errors.0 }}</span>
</p>

 

以上是关于django之form表单验证的主要内容,如果未能解决你的问题,请参考以下文章

django之form表单验证

Django之表单验证

Django之Form表单

Django之Form功能

Django之form组件

django Form验证