註冊功能 1.渲染前端標籤獲取用戶輸入 >>> 渲染標籤 2.獲取用戶輸入傳遞到後端校驗 >>> 校驗數據 3.校驗未經過展現錯誤信息 >>> 展現信息 校驗數據(先後端均可以校驗) 校驗前端後端均可以作,可是前端能夠不作,後端必須得作!!! django form組件 1.渲染標籤 2.校驗數據 3.展現信息 校驗數據 第一步須要在views中寫一個form類 from django import forms class MyForm(forms.Form): name = forms.CharField(max_length=6) password = forms.CharField(max_length=8,min_length=3) email = forms.EmailField(required=True) 第二步實例化form對象 form_obj = MyForm({'name':'jason'}) 第三步查看數據校驗是否合法 form_obj.is_valid() # 只有當全部的字段都校驗經過纔會返回True 第四步查看校驗錯誤的信息 form_obj.errors # 這個裏面放的是全部校驗未經過的字段及錯誤提示 """ { 'name': ['Ensure this value has at most 6 characters (it has 7).'], 'password': ['Ensure this value has at least 3 characters (it has 2).'], 'email': ['Enter a valid email address.'] } """ 第五步查看校驗經過的數據 form_obj.cleaned_data # 符合校驗規則數據都會被放到該對象中 ps:form組件校驗數據的規則從上往下依次取值校驗 校驗經過的放到cleaned_data 校驗失敗的放到errors 注意: form中全部的字段默認都是必須傳值的(required=True) 校驗數據的時候能夠都傳(多傳的數據不會作任何的校驗>>>不會影響form校驗規則) 渲染標籤 form組件只幫你渲染獲取用戶輸入的標籤,不會幫你渲染提交按鈕,須要手動添加 <h1>第一種渲染方式(可擴展性較差)</h1> {{ form_obj.as_p }} {{ form_obj.as_ul }} <h1>第二種渲染方式</h1> <form action=""> <p>{{ form_obj.name.label }}{{ form_obj.name }}</p> <p>{{ form_obj.password.label }}{{ form_obj.password }}</p> <p>{{ form_obj.email.label }}{{ form_obj.email }}</p> <input type="submit"> </form> <h1>第三種渲染標籤的方式</h1> <form action=""> {% for foo in form_obj %} <p>{{ foo.label }}{{ foo }}</p> {% endfor %} </form> 前端取消校驗 參數 novalidate <form action="" method="post" novalidate> </form> form組件提交數據若是數據不合法,頁面上會保留以前用戶輸入的信息 在使用form組件對模型表進行數據校驗的時候,只須要保證字段一致 那麼在建立的對象的時候你就直接**form_obj.cleaned_data <form action="" method="post" novalidate> {% for foo in form_obj %} <p> {{ foo.label }}{{ foo }} <span>{{ foo.errors.0 }}</span> </p> {% endfor %} <input type="submit"> </form> # 鉤子函數 # 局部鉤子函數 (單個字段的校驗利用局部鉤子函數) def clean_name(self): name = self.cleaned_data.get('name') if '666' in name: self.add_error('name','光喊666是不行的,要有真實力!') return name # return仍是要加上的,兼容性考慮 # 全局鉤子函數 (多個字段的校驗利用全局鉤子函數) def clean(self): password = self.cleaned_data.get('password') confirm_password = self.cleaned_data.get('confirm_password') if not password == confirm_password: self.add_error('confirm_password',"兩次密碼不一致,你這個dsb!") return self.cleaned_data # 設置標籤樣式 from django import forms from django.forms import widgets password = forms.CharField(max_length=8,min_length=3,error_messages={ 'max_length': '密碼最長8位', 'required': '密碼不能爲空', 'min_length':'密碼最少3位' },widget=widgets.PasswordInput(attrs={'class':'c1 form-control'})) hobby = forms.ChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),), label="愛好", initial=3, widget=forms.widgets.Select() ) hobby1 = forms.MultipleChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),), label="愛好", initial=[1, 3], widget=forms.widgets.SelectMultiple() ) keep = forms.ChoiceField( label="是否記住密碼", initial="checked", widget=forms.widgets.CheckboxInput() )
forms組件使用完整示例:html
views中定義form類:前端
class RegForm(forms.Form): name = forms.CharField(max_length=10,min_length=3,label='用戶名', error_messages={ 'required':'用戶名不能爲空!', 'invalid':'格式錯誤!', 'max_length':'註冊用戶名長度不能超過10位!', 'min_length':'註冊用戶名長度不能低於3位', }, widget=forms.widgets.Input(attrs={'class':'form-control','style':'width:250px'},)) password = forms.CharField(max_length=16,min_length=3,label='密碼', error_messages={ 'required':'註冊密碼不能爲空!', 'invalid':'格式錯誤!', 'max_length':'密碼超出最大長度16位!', 'min_length':'密碼長度不能低於3位!' }, widget=forms.widgets.PasswordInput(attrs={'class':'form-control','style':'width:250px'}) ) re_password = forms.CharField(max_length=16, min_length=3,label='再次輸入密碼', error_messages={ 'required': '註冊密碼不能爲空!', 'invalid': '格式錯誤!', 'max_length': '密碼超出最大長度16位!', 'min_length': '密碼長度不能低於3位!' }, widget=forms.widgets.PasswordInput( attrs={'class': 'form-control', 'style': 'width:250px'}) ) cellphone = forms.CharField(max_length=14,min_length=10,label='請輸入手機號',error_messages={ 'required': '註冊手機號不能爲空!', 'invalid': '格式錯誤!', 'max_length': '手機號長度不合法!', 'min_length': '手機號長度不合法!' }, widget=forms.widgets.Input(attrs={'class':'form-control','style':'width:250px','id':'cellphone'}) ) def clean_name(self): name = self.cleaned_data.get("name") if not name.isalpha(): self.add_error('name','用戶名必須由字母數字組成!') elif name[0].isdigit(): self.add_error('name','用戶名不能以數字開頭!') elif models.User.objects.filter(name=name): self.add_error('name','該用戶名已存在!') return name def clean(self): password = self.cleaned_data.get("password") re_password = self.cleaned_data.get('re_password') if password != re_password: self.add_error('re_password','兩次密碼不一致!') elif password == '123': self.add_error('password','當前密碼過於簡單!') return self.cleaned_data def clean_cellphone(self): cellphone = self.cleaned_data.get("cellphone") regExp = "^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147))\\d{8}$" if not re.findall(regExp,cellphone): self.add_error('cellphone','請輸入正確的手機號!') elif models.User.objects.filter(cellphone = cellphone): self.add_error('cellphone','該手機號已註冊!請換一個再試!') return cellphone
前端渲染代碼:git
因爲引入了許多第三方樣式,沒有導入JS,CSS樣式等部分,截取了body部分做爲示例django
<body> <div class="container" id="particles-js"> <div id="main-div"> <h3 style="text-align: center">歡迎註冊圖書管理系統</h3> <form action="" method="post" style="width: 250px;margin: 20px auto" autocomplete="off" novalidate> {% for form_datum in form_data %} <p>{{ form_datum.label }}{{ form_datum }} <span style="color: red">{{ form_datum.errors.0 }}</span> </p> {% endfor %} <span>請輸入驗證碼:</span> <p > <input type="text" class="form-control" name="yzm" style="width: 120px;display:inline-block;"> <input href="#" class="btn btn-info feachBtn" style="width: 130px;float: right;" value="獲取手機驗證碼"> </p> <span style="color: red">{{ yzm }}</span> <p style="padding: 10px 0;"><input type="submit" class="btn btn-info btn-block" value="註冊"></p> </form> </div> </div> </body>
views視圖函數處理部分:後端
def register(request): form_data = RegForm() if request.method == "POST": form_data = RegForm(request.POST) if form_data.is_valid(): #檢查是否經過校驗,沒有則返回前端error信息,經過則註冊 dic = dict(form_data.cleaned_data) dic["user_type"] = 'user' dic.pop('re_password') # dic['cellphone'] = request.session.get("cellphone") models.User.objects.create(**dic) return redirect('/admins/show-book/') return render(request, "reg.html",locals())