1. 程式人生 > >django之form表單驗證

django之form表單驗證

lds nbsp sub att hasattr () form表單 con data

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表單驗證