Django form表單的校驗、局部鉤子及全局鉤子

#form表單的校驗、局部鉤子及全局鉤子#

## views.py 視圖函數 ##css

from django import forms                #調用forms模塊
    from django.forms import widgets        #調用widgets模塊,用來對form組件的參數配置。
    from django.core.exceptions import ValidationError  #調用 ValidationError 模塊。用來手動觸發raise錯誤。
    from fileupdate.models import *      #載入必要的數據庫列表。


    class FormReg(forms.Form):

        name = forms.CharField(min_length=4, widget=widgets.TextInput(attrs={'class': 'form-control '}), label='姓名',
                               error_messages={'required': '*不能爲空', })
        pwd = forms.CharField(min_length=4, widget=widgets.PasswordInput(attrs={'class': 'form-control'}), label='密碼')
        r_pwd = forms.CharField(min_length=4, widget=widgets.PasswordInput(attrs={'class': 'form-control'}),
                                label='確認密碼')
        email = forms.EmailField(widget=widgets.EmailInput(attrs={'class': 'form-control'}), label='郵箱')
        tel = forms.CharField(max_length=13, label='電話', widget=widgets.TextInput(attrs={'class': 'form-control'}))
        ##字段的校驗,經過對widget的屬性設置,可定義INPUT標籤的type類型,以及標籤的其餘屬性。經過對label設置,能夠自定義form渲染時的標籤名,
        ##另外,經過對error_messages屬性設置,可對驗證信息進行自定義。注意:字典中錯誤信息的key值是固定的
    
        def clean_name(self):    #局部鉤子   注意:名字必須爲clean_%s ,這是根據源碼來設置的。
                                #其原理是,當字段校驗完畢後,再進行查找是否有以clean_開頭的函數名,若是有,就調用該函數,
                                #運行咱們自定義的函數,若是知足條件就返回當前被校驗字段的內容。不然手動觸發ValidationError錯誤,源碼中會捕獲並將值返回。
            val = self.cleaned_data.get('name')     #經過cleaned_data得到對應字段的'乾淨數據'
            user_obj = User.objects.filter(name=val).first()  #與對應的數據庫中字段相比較,並得到一個字段對象
            if not user_obj:   #對字段進行判斷,若是爲空(數據庫中沒有對應的名字),那麼返回這個校驗值。
                return val
            else:
                raise ValidationError('名字存在')   #若是存在,那麼手動觸發異常(異常名爲ValidationError),並設置自定義內容。
    
        def clean(self):   #全局鉤子  注意:名字必須爲clean,這是根據源碼來設置的。
                         #其原理是對校驗完畢的字段,再進行字段間的校驗。當字段校驗完畢,查找是否有clean的函數,若是有就運行該
                         #函數,其功能是對全部校驗的字段進行校驗比對。若是知足條件,就將cleaned_data返回(這與源碼相匹配)
                         #若是不知足就手動觸發ValidationError錯誤。
            pwd = self.cleaned_data.get('pwd') 
            r_pwd = self.cleaned_data.get('r_pwd')
            if pwd and r_pwd:   #若是兩個字段中一個爲空值那麼就不用再進行校驗。直接返回cleaned_data,經過校驗功能返回錯誤信息。
                if pwd == r_pwd:
                    return self.cleaned_data
                else:
                    raise ValidationError('兩次密碼不一致!')
            else:
                return self.cleaned_data

    def reg(request):
    
        if request.method == 'POST':  #若是是一次POST提交,那麼進行校驗。
            formreg = FormReg(request.POST)  #對提交的信息實例化。
    
            if formreg.is_valid():  #經過is_valid()方法進行判斷,(注意:當執行這個函數時,將對全部字段進行校驗,運行局部鉤子和全局鉤子)
                return HttpResponse('OK')
            else:
                print('cleaneddata', formreg.cleaned_data)
                print('errordata', formreg.errors)
                error = formreg.errors.get('__all__') #當設置了全局鉤子時,要設置一個變量來得到全局鉤子返回的錯誤信息。
                            #這是因爲,全局鉤子的錯誤在form對象的errors中,當clean()方法拋出異常時,源碼會自動捕獲,並將錯誤
                            #存儲在errors字典中,其中鍵名'__all__'就是全局鉤子的變量。
                return render(request, 'reg.html', locals())
    
        formreg = FormReg()   #當爲get請求時,實例化一個空的對象,經過這個空的實例化對象能夠渲染前段,自動生成form表單。
        return render(request,'reg.html', locals())

 

## reg.html 前端頁面 ##html

  <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>reg</title>
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <form action="" method="post" novalidate>
                    {% csrf_token %}
                    {% for field in formreg %}
                        <p>
                            <label for="">{{ field.label }}</label>
                        {{ field }} 
                            {% if field.name == 'r_pwd' %}
                                <span style="color: crimson">{{ field.errors.0 }} {{ error.0 }}</span>
                            {% else %}
                                <span style="color: crimson">{{ field.errors.0 }}</span>
                            {% endif %}
    
                        </p>
                    {% endfor %}
    
                    <p><input type="submit"></p>
                </form>
            </div>
        </div>
    </div>
    
    </body>
    </html>
View Code
相關文章
相關標籤/搜索