django Form 表單 總結與小實例

開頭寄語:javascript

這幾天一直在看Django的form表單驗證,而後想對於這幾天要有個總結。css

  • 首先,先來看一下找到的一個form表單驗證的流程:

驗證過程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_<field>&()的最後必須返回驗證完畢或修改後的值.java

  • 補充小插曲

咱們在寫表單類的時候 通常也繼承froms.Form,可是也見過繼承ModleForm,應該來講繼承那個均可以,我的認爲繼承ModleForm時,主要是再寫表單類的時候方便些,好比經過以下方式寫表單類jquery

from app01.models import Moment
from django import forms
from django.forms import ModelForm


class MomentForm(ModelForm):

    class Meta:
        model = Moment      # Models類名稱
        fields = "__all__"  # 導入全部的字段
        # fields = ['content', 'user_name']

 

 

 

  • 下面是本身寫的一個小實例,內容包括 form表單驗證與session

需求以下:django

用戶訪問首頁,在首頁點擊註冊,對註冊表單進行驗證,登陸成功後進入後臺管理界面session

表單類:app

表單中包含input標籤 select標籤 checkbox標籤 也定義了一些自定義的驗證邏輯,這裏也看了一些資料,我認爲在定義clean_xx 函數時 最後要return 驗證字段的值,而重寫clean()方法時,最後要return clean_data。函數

# 註冊頁面手機號驗證
def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    value = str(value)
    if not mobile_re.match(value):
        raise forms.ValidationError('手機號碼格式錯誤')




class RegisterForm(forms.Form):
    username = forms.CharField(
        error_messages={'required': '用戶名不能爲空', 'min_length': '最小長度爲4', 'max_length': '最大長度爲30'},
        max_length=30,
        min_length=4,
    )

    password = forms.CharField(
        error_messages={'required': '密碼不能爲空'}
    )

    password_again = forms.CharField(
        error_messages={'required': '密碼不能爲空',}
    )
    email = forms.EmailField(
        required=False,
        error_messages={'invalid': '郵箱格式錯誤'}
    )
    phone = forms.IntegerField(validators=[mobile_validate],
                               error_messages={'required': '手機號不能爲空', 'invalid': '必須輸入數字'}
                               )
    roles = Role.objects.all().values_list('id', 'role_name')
    role = forms.CharField(
        error_messages={'required': '角色不能爲空'},
        widget=forms.widgets.Select(choices=roles, attrs={'class': 'c1'}))
    marry_choice = (
        ('0', ''),
        ('1', ''),
        ('2', '已婚'),
        ('3', '未婚'),
    )
    marry = forms.MultipleChoiceField(
        error_messages={'required': '選擇不能爲空'},
        choices=marry_choice, widget=forms.CheckboxSelectMultiple())

    favors = Favor.objects.all().values_list('id', 'favor_name')
    favor = forms.CharField(
        error_messages={'required': '愛好不能爲空'},
        widget=forms.widgets.Select(choices=favors, attrs={'class': 'c1', 'multiple': 'multiple'}))
    code = forms.CharField(
        error_messages={'required': '驗證碼不能爲空'}
    )

    # 自定義驗證  驗證password
    def clean_password(self):
        cleaned_data = super(RegisterForm, self).clean()
        user_data = cleaned_data.get('password')
        if user_data == 'XXX':
            raise forms.ValidationError(u'密碼太簡單了')
        return user_data

    # 驗證兩次輸入的密碼是否一致
    def clean_password_again(self):
        password = self.cleaned_data['password']
        password_again = self.cleaned_data['password_again']
        if password != password_again:
            raise forms.ValidationError('兩次密碼不一致')
        return password_again

    def __init__(self, *args, **kwargs):
        super(RegisterForm, self).__init__(*args, **kwargs)
        self.fields['role'] = forms.CharField(
            widget=forms.widgets.Select(choices=Role.objects.all().values_list('id', 'role_name'), attrs={'class': 'c1'})
        )
        self.fields['favor'] = forms.CharField(
            widget=forms.widgets.Select(choices=Favor.objects.all().values_list('id', 'favor_name'),
                                        attrs={'class': 'c1'})
        )



    # 驗證選擇婚姻是否正確
    def clean_marry(self):
        data_list = self.cleaned_data['marry']
        if len(data_list) == 2:
            if '0' and '1' in data_list:
                raise forms.ValidationError('男女選擇有誤!')
            elif '2' and '3' in data_list:
                raise forms.ValidationError('婚姻選擇有誤!')
            else:
                return data_list
        else:
            raise forms.ValidationError('請選擇男女和婚姻!')

前段htmlpost

這裏面 input標籤 包括本身寫的 也有 經過Django自動生成的。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>用戶註冊</title>
        <link rel="stylesheet" type="text/css" href="/statics/css/one.css">
    </head>
    <body>
        <div class="register-page">
            <div class="mid-css">
                <form method="post" action="/register/">
                     <div class="commons-css">
                         <span class="register-span">用戶名:</span>
                         <input type="text" name="username" placeholder="請輸入用戶名">
                         <span class="error-info">{{ errors.username.0 }}</span>
                    </div>

                     <div class="commons-css">
                         <span class="register-span">密碼:</span>
                         <input type="text" name="password" placeholder="請輸入密碼">
                          <span class="error-info">{{ errors.password.0 }}</span>
                    </div>

                     <div class="commons-css">
                         <span class="register-span">確認密碼:</span>
                         <input type="text" name="password_again" placeholder="請輸入密碼">
                          <span class="error-info">{{ errors.password_again.0 }}</span>
                    </div>

                     <div class="commons-css">
                         <span class="register-span">郵箱:</span>
                         <input type="text" name="email" placeholder="請輸入郵箱">
                          <span class="error-info">{{ errors.email.0 }}</span>
                    </div>

                     <div class="commons-css">
                         <span class="register-span">手機號:</span>
                         <input type="text" name="phone" placeholder="請輸入手機號">
                          <span class="error-info">{{ errors.phone.0 }}</span>
                    </div>

                     <div class="commons-css">
                         <span class="register-span">角色:</span>
                         {{ form.role }}
                          <span class="error-info">{{ errors.role.0 }}</span>
                    </div>

                    <div class="favor-css ClearFloat">
                         <span class="favor-span">婚姻情況:</span>
                         {{ form.marry }}
                          <span class="error-info">{{ errors.marry.0 }}</span>
                    </div>


                     <div class="commons-css">
                         <span class="register-span">愛好:</span>
                         {{ form.favor }}
                          <span class="error-info">{{ errors.favor.0 }}</span>
                    </div>




                    <div class="commons-css">
                        <span class="register-span">驗證碼:</span>
                        <input type="text" name="code" style="width: 150px">
                        <span class="span-code" onclick= "GetCode(this)" id="span">點擊獲取</span>
                        {% if errors.code.0 %}
                            <span class="error-info">{{ errors.code.0 }}</span>
                        {% else %}
                            <span class="error-info">{{ code_error.error_code_info }}</span>
                        {% endif %}
                   </div>
                    <div class="register-submit">
                        <input type="button" value="重置">
                        <input type="submit" value="註冊">
                    </div>
                </form>
            </div>
        </div>
      <script type="text/javascript" src="/statics/js/jquery-3.2.1.min.js"></script>
        <script type="text/javascript" src="/statics/js/one.js"></script>
    </body>
</html>

後臺處理:

def register(request):
    if request.method == 'POST':
        register_obj = RegisterForm(request.POST)
        ret = register_obj.is_valid()
        if ret:
            input_code = register_obj.cleaned_data['code']
            old_code = request.session['code']
            if input_code.upper() == old_code.upper():
                request.session['is_login'] = True
                print(register_obj.cleaned_data)
                return HttpResponseRedirect('/manager/')
            else:
                error_code_info = {'error_code_info': '驗證碼輸入錯誤'}
                return render(request, 'forms/register.html', {'errors': register_obj.errors,
                                                               'code_error': error_code_info, 'form': register_obj})
        else:
            return render(request, 'forms/register.html', {'errors': register_obj.errors, 'form': register_obj})
    else:
        register_obj = RegisterForm()
        return render(request, 'forms/register.html', {'form': register_obj})

頁面效果:

相關文章
相關標籤/搜索