Django的Form主要具備一下幾大功能:html
一、view中建立Form類並進行函數處理python
from django import forms # 導入forms class FM(forms.Form): user = forms.CharField() pwd = forms.CharField() email = forms.EmailField() def fm(request): if request.method == "GET": obj = FM() return render(request, 'fm.html', {'obj': obj}) elif request.method == "POST": # 獲取用戶全部數據 # 每條數據請求的驗證 # 成功:獲取全部的正確的信息 # 失敗:顯示錯誤信息 obj = FM(request.POST) # 生成from表單驗證對象實例 r1 = obj.is_valid() # 獲取obj對象是否有效 if r1: # obj.cleaned_data print(r1) print(obj.changed_data) else: print(r1) print(obj.errors.as_json()) # 錯誤信息字典形式 # {"user": [{"message": "This field is required.", "code": "required"}], # "pwd": [{"message": "This field is required.", "code": "required"}], # "email": [{"message": "This field is required.", "code": "required"}]} print(obj.errors['user'][0]) return redirect("/fm/")
二、生成HTMLjquery
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/fm/" method="POST"> {% csrf_token %} {# <!--第一種 input框形式-->#} {# <p><input type="text" name="user"/> {{ obj.errors.user.0 }}</p> <!--user pwd email 必需要跟視圖中的繼承forms.Form類中的相應實例名稱一致-->#} {# <p><input type="text" name="pwd"/> {{ obj.errors.pwd.0 }}</p>#} {# <p><input type="text" name="email"/> {{ obj.errors.email.0 }}</p>#} <!--第二種 obj.user框形式--> <p>{{ obj.user }} {{ obj.errors.user.0 }}</p> <!-- 相似於view視圖中的 obj.errors['user'][0]--> <p>{{ obj.pwd }} {{ obj.errors.pwd.0 }}</p> <p>{{ obj.email }}{{ obj.errors.email.0 }}</p> {# <!--第三種 obj.as_p、obj.as_ul、 obj.as_table(須要在外面添加table標籤)框形式,生成方便,自定義樣式不強-->#} {# {{ obj.as_p }}#} {# {{ obj.as_ul }}#} {# <table>#} {# {{ obj.as_table }}#} {# </table>#} <input type="submit" value="提交" /> </form> </body> </html>
建立Form類時,主要涉及到 fields【字段】 和 wiegets【插件】,功能特性:字段用於對用戶請求數據的驗證,插件用於自動生成HTML(保留上一次提交的數據)。使用場景:一、在新url方式操做時,字段和插件都須要用到,由於在from提交以後,頁面也會被刷新,而插件能夠保留上一次的提交數據。二、在用Ajax請求操做時,能夠只用到字段的驗證功能,由於Ajax請求頁面不會刷新,上一次提交數據仍然保留在頁面,固然在用Ajax請求操做時也可使用插件。git
一、Django內置字段以下:web
1 Field 2 required=True, 是否容許爲空 3 widget=None, HTML插件 4 label=None, 用於生成Label標籤或顯示內容 5 initial=None, 初始值 6 help_text='', 幫助信息(在標籤旁邊顯示) 7 error_messages=None, 錯誤信息 {'required': '不能爲空', 'invalid': '格式錯誤'} 8 show_hidden_initial=False, 是否在當前插件後面再加一個隱藏的且具備默認值的插件(可用於檢驗兩次輸入是否一直) 9 validators=[], 自定義驗證規則 10 localize=False, 是否支持本地化 11 disabled=False, 是否能夠編輯 12 label_suffix=None Label內容後綴 13 14 15 CharField(Field) 16 max_length=None, 最大長度 17 min_length=None, 最小長度 18 strip=True 是否移除用戶輸入空白 19 20 IntegerField(Field) 21 max_value=None, 最大值 22 min_value=None, 最小值 23 24 FloatField(IntegerField) 25 ... 26 27 DecimalField(IntegerField) 28 max_value=None, 最大值 29 min_value=None, 最小值 30 max_digits=None, 總長度 31 decimal_places=None, 小數位長度 32 33 BaseTemporalField(Field) 34 input_formats=None 時間格式化 35 36 DateField(BaseTemporalField) 格式:2015-09-01 37 TimeField(BaseTemporalField) 格式:11:12 38 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 39 40 DurationField(Field) 時間間隔:%d %H:%M:%S.%f 41 ... 42 43 RegexField(CharField) 44 regex, 自定製正則表達式 45 max_length=None, 最大長度 46 min_length=None, 最小長度 47 error_message=None, 忽略,錯誤信息使用 error_messages={'invalid': '...'} 48 49 EmailField(CharField) 50 ... 51 52 FileField(Field) 53 allow_empty_file=False 是否容許空文件 54 55 ImageField(FileField) 56 ... 57 注:須要PIL模塊,pip3 install Pillow 58 以上兩個字典使用時,須要注意兩點: 59 - form表單中 enctype="multipart/form-data" 60 - view函數中 obj = MyForm(request.POST, request.FILES) 61 62 URLField(Field) 63 ... 64 65 66 BooleanField(Field) 67 ... 68 69 NullBooleanField(BooleanField) 70 ... 71 72 ChoiceField(Field) 73 ... 74 choices=(), 選項,如:choices = ((0,'上海'),(1,'北京'),) 75 required=True, 是否必填 76 widget=None, 插件,默認select插件 77 label=None, Label內容 78 initial=None, 初始值 79 help_text='', 幫助提示 80 81 82 ModelChoiceField(ChoiceField) 83 ... django.forms.models.ModelChoiceField 84 queryset, # 查詢數據庫中的數據 85 empty_label="---------", # 默認空顯示內容 86 to_field_name=None, # HTML中value的值對應的字段 87 limit_choices_to=None # ModelForm中對queryset二次篩選 88 89 ModelMultipleChoiceField(ModelChoiceField) 90 ... django.forms.models.ModelMultipleChoiceField 91 92 93 94 TypedChoiceField(ChoiceField) 95 coerce = lambda val: val 對選中的值進行一次轉換 96 empty_value= '' 空值的默認值 97 98 MultipleChoiceField(ChoiceField) 99 ... 100 101 TypedMultipleChoiceField(MultipleChoiceField) 102 coerce = lambda val: val 對選中的每個值進行一次轉換 103 empty_value= '' 空值的默認值 104 105 ComboField(Field) 106 fields=() 使用多個驗證,以下:即驗證最大長度20,又驗證郵箱格式 107 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) 108 109 MultiValueField(Field) 110 PS: 抽象類,子類中能夠實現聚合多個字典去匹配一個值,要配合MultiWidget使用 111 112 SplitDateTimeField(MultiValueField) 113 input_date_formats=None, 格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y'] 114 input_time_formats=None 格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] 115 116 FilePathField(ChoiceField) 文件選項,目錄下文件顯示在頁面中 117 path, 文件夾路徑 118 match=None, 正則匹配 119 recursive=False, 遞歸下面的文件夾 120 allow_files=True, 容許文件 121 allow_folders=False, 容許文件夾 122 required=True, 123 widget=None, 124 label=None, 125 initial=None, 126 help_text='' 127 128 GenericIPAddressField 129 protocol='both', both,ipv4,ipv6支持的IP格式 130 unpack_ipv4=False 解析ipv4地址,若是是::ffff:192.0.2.1時候,可解析爲192.0.2.1, PS:protocol必須爲both才能啓用 131 132 SlugField(CharField) 數字,字母,下劃線,減號(連字符) 133 ... 134 135 UUIDField(CharField) uuid類型 UUID是根據MAC以及當前時間等建立的不重複的隨機字符串 136 ...
二、Django內置插件:ajax
1 TextInput(Input) 2 NumberInput(TextInput) 3 EmailInput(TextInput) 4 URLInput(TextInput) 5 PasswordInput(TextInput) 6 HiddenInput(TextInput) 7 Textarea(Widget) 8 DateInput(DateTimeBaseInput) 9 DateTimeInput(DateTimeBaseInput) 10 TimeInput(DateTimeBaseInput) 11 CheckboxInput 12 Select 13 NullBooleanSelect 14 SelectMultiple 15 RadioSelect 16 CheckboxSelectMultiple 17 FileInput 18 ClearableFileInput 19 MultipleHiddenInput 20 SplitDateTimeWidget 21 SplitHiddenDateTimeWidget 22 SelectDateWidget
2.一、經常使用的內置插件演示:正則表達式
1 # 單radio,值爲字符串 2 # user = fields.CharField( 3 # initial=2, 4 # widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),)) 5 # ) 6 7 # 單radio,值爲字符串 8 # user = fields.ChoiceField( 9 # choices=((1, '上海'), (2, '北京'),), 10 # initial=2, 11 # widget=widgets.RadioSelect 12 # ) 13 14 # 單select,值爲字符串 15 # user = fields.CharField( 16 # initial=2, 17 # widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)) 18 # ) 19 20 # 單select,值爲字符串 21 # user = fields.ChoiceField( 22 # choices=((1, '上海'), (2, '北京'),), 23 # initial=2, 24 # widget=widgets.Select 25 # ) 26 27 # 多選select,值爲列表 28 # user = fields.MultipleChoiceField( 29 # choices=((1,'上海'),(2,'北京'),), 30 # initial=[1,], 31 # widget=widgets.SelectMultiple 32 # ) 33 34 35 # 單checkbox 36 # user = fields.CharField( 37 # widget=widgets.CheckboxInput() 38 # ) 39 40 41 # 多選checkbox,值爲列表 42 # user = fields.MultipleChoiceField( 43 # initial=[2, ], 44 # choices=((1, '上海'), (2, '北京'),), 45 # widget=widgets.CheckboxSelectMultiple 46 # )
2.二、Form操做動態Select數據:數據庫
1 # forms.py 在app目錄下建立forms.py文件,來專門存放form驗證的代碼 2 from django.forms import widgets,forms,fields 3 from app01 import models 4 5 class UserForm(forms.Form): 6 7 name = fields.CharField( 8 required=False, 9 widget=widgets.TextInput(attrs={'class':'c1'}) 10 ) 11 12 email = fields.EmailField( 13 max_length=12, 14 widget=widgets.TextInput(attrs={"class":"c2"}) 15 ) 16 17 user_type = fields.ChoiceField 18 ### 第一種form動態獲取select數據 19 #靜態變量,僅在程序第一次加載時執行,從數據庫讀取數據保存至內存,重啓服務才能從數據庫獲取最新數據 20 # choices=models.UserType.objects.values_list('id','type_name'), 21 22 ### 第二種form動態獲取select數據,自定義構造方法, 23 choices=[], 24 widget=widgets.Select 25 ) 26 27 user_type2 = fields.CharField(widget=widgets.Select(choices=[])) #fields['user_type2'].widget.choices 28 29 def __init__(self,*args,**kwargs): 30 super(UserForm,self).__init__(*args,**kwargs) 31 32 # 構造方法中實例變量會在每次實例化後執行 33 self.fields["user_type"].choices = models.UserType.objects.values_list('id','type_name') 34 self.fields['user_type2'].widget.choices = models.UserType.objects.values_list('id','type_name') 35 36 37 38 # view.py 在view.py視圖函數中去調用From驗證 39 40 from django.shortcuts import render 41 from app01 import models 42 43 def index(request): 44 from app01.forms import UserForm 45 ### 第一種form動態獲取select數據 46 #obj = UserForm() # 實例化UserForm類 47 # obj.fields["user_type"].choices=models.UserType.objects.values_list('id','type_name') #每次刷新web頁面就至關於實例化一次UserForm類,從而從數據庫獲取最新數據 48 49 ### 第二種form動態獲取select數據,自定義構造方法 50 obj = UserForm() #實例化UserForm類,這裏只須要實例化,而form UserForm類中重寫的構造方法中的實例變量會在每次實例化以後執行一次 51 return render(request,'index.html',{'obj':obj}) 52 53 54 55 #HTML 56 <body> 57 <p>{{ obj.name }}</p> 58 <p>{{ obj.email }}</p> 59 <p>{{ obj.user_type }}</p> 60 <p>{{ obj.user_type2 }}</p> 61 </body>
1 ##form.py 2 #ModelChoiceField具體字段以下: 3 ModelChoiceField(ChoiceField) 4 ... django.forms.models.ModelChoiceField 5 queryset, # 查詢數據庫中的數據 6 empty_label="---------", # 默認空顯示內容 7 to_field_name=None, # HTML中value的值對應的字段 8 limit_choices_to=None # ModelForm中對queryset二次篩選 ### 9 10 11 12 from django.forms import widgets,forms,fields 13 from django.forms.models import ModelChoiceField #django本身幫咱們提供的 14 15 class UserForm(forms.Form): 16 user_type3 = ModelChoiceField( 17 queryset=models.UserType.objects.all(), 18 to_field_name="id", #html中的value的值的對應字段,通常狀況下只用id 19 empty_label="請選擇用戶類型", #默認空顯示內容 20 ) 21 22 23 ##ModelChoiceField必須跟model中的__str__函數想結合使用: 24 class UserType(models.Model): 25 type_name = models.CharField(max_length=32) 26 27 def __str__(self): #必須跟__str__這個函數結合使用 28 return self.type_name 29 30 31 32 33 34 #view.py 35 36 def index(request): 37 38 from app01.forms import UserForm 39 obj = UserForm() 40 41 return render(request,'index.html',{'obj':obj}) 42 43 44 #HTML 45 <body> 46 <p>{{ obj.user_type3 }}</p> 47 </body>
三、Form內置鉤子進行驗證:django
django form中還預留了鉤子,主要有三個類型的鉤子:_clean_fields (單個字段驗證,,如:登陸頁面user or password字段)、_clean_fields (總體驗證,如:登陸頁面總體)、_post_clean(預留的鉤子,主要坐收尾工做)json
3.一、_clean_fields
1 from app01 import models 2 from django.core.exceptions import ValidationError #源碼裏面拋出的異常 3 class RegisterForm(forms.Form): 4 user = fields.CharField() #下面的方法要想執行,先經過這邊正則驗證 5 email = fields.EmailField() 6 #根據源碼,咱們知道在咱們本身自定義的form中,是 定義clean_字段名 方法,去驗證,而後賦值給 cleaned_data 7 #clean_%s 這個函數必需要有返回值,賦值給self.cleaned_data['%s'] 8 def clean_user(self): 9 #註冊的時候,若是存在此用戶,則報錯,沒有,則繼續執行 10 c = models.User.objects.filter(name=self.cleaned_data['user'].count()) 11 if not c: 12 return self.cleaned_data['user'] 13 else: 14 raise ValidationError('用戶名已經存在',code="xxxx") #存在就包異常 15 16 17 def clean_email(self): 18 19 return self.cleaned_data['email'] #這邊必須返回一個值
3.二、_clean_form
1 from app01 import models 2 from django.core.exceptions import ValidationError #源碼裏面拋出的異常 3 class RegisterForm(forms.Form): 4 user = fields.CharField() #下面的方法要想執行,先經過這邊正則驗證 5 pwd = fields.CharField() 6 7 8 def clean(self): 9 c = models.User.objects.filter(name=self.cleaned_data['user'],pwd=self.cleaned_data['pwd']).count() 10 if not c: 11 return self.cleaned_data #這邊必須有一個返回值,由於源碼裏面有返回值 12 else: 13 raise ValidationError("用戶名或密碼錯誤",code="xxxxx") #這個異常應該給總體,不該該給某一個字段
3.三、單個字段錯誤提示和form總體錯誤提示
1 obj.errors: 2 { 3 #self._clean_form() 返回的錯誤信息,也就是總體返回的錯誤信息,有的地方寫成: NON_FIFLD_ERRORS:[],其實就是代指的__all__ 4 '__all__':[], 5 # clean_user和clean_pwd返回的錯誤信息,就是單個驗證返回的錯誤信息 6 'user':[{'code':"required",'message':'xxxx'}], 7 'pwd':[{'code':"required",'message':'xxxx'}] 8 }
四、自定義驗證規則:
from django.forms import Form from django.forms import widgets from django.forms import fields from django.core.validators import RegexValidator class MyForm(Form): user = fields.CharField( validators=[RegexValidator(r'^[0-9]+$', '請輸入數字'), RegexValidator(r'^159[0-9]+$', '數字必須以159開頭')], )
import re from django.forms import Form from django.forms import widgets from django.forms import fields from django.core.exceptions import ValidationError # 自定義驗證規則 def mobile_validate(value): mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') if not mobile_re.match(value): raise ValidationError('手機號碼格式錯誤') class PublishForm(Form): title = fields.CharField(max_length=20, min_length=5, error_messages={'required': '標題不能爲空', 'min_length': '標題最少爲5個字符', 'max_length': '標題最多爲20個字符'}, widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': '標題5-20個字符'})) # 使用自定義驗證規則 phone = fields.CharField(validators=[mobile_validate, ], error_messages={'required': '手機不能爲空'}, widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': u'手機號碼'})) email = fields.EmailField(required=False, error_messages={'required': u'郵箱不能爲空','invalid': u'郵箱格式錯誤'}, widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': u'郵箱'}))
# 自定義方法 from django import forms from django.forms import fields from django.forms import widgets from django.core.exceptions import ValidationError from django.core.validators import RegexValidator class FInfo(forms.Form): username = fields.CharField(max_length=5, validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid extension.', 'invalid')], ) email = fields.EmailField() def clean_username(self): """ Form中字段中定義的格式匹配完以後,執行此方法進行驗證 :return: """ value = self.cleaned_data['username'] if "666" in value: raise ValidationError('666已經被玩爛了...', 'invalid') return value
#同時生成多個標籤進行驗證 from django.forms import Form from django.forms import widgets from django.forms import fields from django.core.validators import RegexValidator ############## 自定義字段 ############## class PhoneField(fields.MultiValueField): def __init__(self, *args, **kwargs): # Define one message for all fields. error_messages = { 'incomplete': 'Enter a country calling code and a phone number.', } # Or define a different message for each field. f = ( fields.CharField( error_messages={'incomplete': 'Enter a country calling code.'}, validators=[ RegexValidator(r'^[0-9]+$', 'Enter a valid country calling code.'), ], ), fields.CharField( error_messages={'incomplete': 'Enter a phone number.'}, validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid phone number.')], ), fields.CharField( validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid extension.')], required=False, ), ) super(PhoneField, self).__init__(error_messages=error_messages, fields=f, require_all_fields=False, *args, **kwargs) def compress(self, data_list): """ 當用戶驗證都經過後,該值返回給用戶 :param data_list: :return: """ return data_list ############## 自定義插件 ############## class SplitPhoneWidget(widgets.MultiWidget): def __init__(self): ws = ( widgets.TextInput(), widgets.TextInput(), widgets.TextInput(), ) super(SplitPhoneWidget, self).__init__(ws) def decompress(self, value): """ 處理初始值,當初始值initial不是列表時,調用該方法 :param value: :return: """ if value: return value.split(',') return [None, None, None]
五、Form內置序列化錯誤信息:
1 #form.py 2 rom django import forms 3 from django.forms import fields,widgets 4 5 class LoginForm(forms.Form): 6 username = fields.CharField() #這跟login.html中的input標籤的name屬性的值一致 7 password = fields.CharField( 8 max_length=64, 9 min_length=12 10 ) 11 12 13 14 15 16 17 #view 中的login 函數 18 #第一種 使用ErrorDict中的as_json函數,不過在HTML中相應獲取錯誤信息須要反解兩次 19 from django.shortcuts import render,HttpResponse 20 import json 21 def login(request): 22 ret = {'status':True,'error':None,'data':None} 23 if request.method == "GET": 24 return render(request,'login.html') 25 elif request.method == "POST": 26 obj = LoginForm(request.POST) 27 if obj.is_valid(): 28 print(obj.cleaned_data) 29 else: 30 # print(type(obj.errors)) 經過打印類型得知是屬於ErrorDict 31 from django.forms.utils import ErrorDict #經過源碼得知:as_data 返回的是原生的字典,as_json()是相似json格式的字符串 32 ret['error'] = obj.errors.as_json() 33 return HttpResponse(json.dumps(ret)) #由於as_json()和json.dumps 至關於序列化了兩次 34 35 36 37 #第二張自定義JsonCustomEncoder類 38 from django.core.exceptions import ValidationError 39 import json 40 class JsonCustomEncoder(json.JSONEncoder): #直接在cls=JsonCustomEncoder類名,去序列化複雜的數據類型 41 def default(self,field): 42 if isinstance(field,ValidationError): # 43 # # from django.core.exceptions import ValidationError #看一下這個異常,發現field的字段和錯誤信息都保存在這個ValidationError對象裏 44 return {'code':field.code,'messages':field.messages} 45 else: 46 return json.JSONEncoder.default(self,field) 47 48 49 50 from django.shortcuts import render,HttpResponse 51 import json 52 53 def login(request): 54 ret = {'status':True,'error':None,'data':None} 55 if request.method == "GET": 56 return render(request,'login.html') 57 elif request.method == "POST": 58 obj = LoginForm(request.POST) 59 if obj.is_valid(): 60 print(obj.cleaned_data) 61 else: 62 ret['error'] = obj.errors.as_data() 63 # for k,v in obj.errors.as_data().items(): 64 # print(k,v) 經過打印發現as_data後 value是一個ValidationError對象 65 # ret = {'k1':'v1','k2':ValueError()} #像這種複雜數據類型,json是不能序列化的,咱們只能作局部處理 66 #這邊cls 是序列化的時候,對每個字段序列化的時候,都會調用一個它的default方法,所以重寫JsonCustomEncoder類中default方法來進行復雜狀況下的序列化操做 67 result = json.dumps(ret,cls=JsonCustomEncoder) 68 return HttpResponse(result) 69 70 71 72 73 #HTML 74 """ 75 <body> 76 <form id="fm"> 77 {% csrf_token %} 78 <p><input type="text" name="username" /></p> #這邊username 須要跟 from 裏面的字段 是如出一轍 79 <p><input type="text" name="password" /></p> 80 <a id="submit">提交</a> 81 </form> 82 83 <script src="/static/jquery-1.12.4.js"></script> 84 <script> 85 $(function(){ 86 $('#submit').click(function(){ 87 $.ajax({ 88 url:'/login/', 89 type:'post', 90 data:$('#fm').serialize(), 91 sucess:function(arg){ 92 //console.log(arg); 93 arg = JSON.parse(arg); 94 console.log(arg) 95 }, 96 error:function(){ 97 98 } 99 }) 100 }) 101 }) 102 </script> 103 </body>""" 104 105 106 107 108 #返回的數據類型爲: 109 110 "{\"data\": null, \"status\": true, \"error\": {\"username\": [{\"code\": \"required\", \"messages\": [\"This field is required.\"]}], 111 \"password\": [{\"code\": \"required\", \"messages\": [\"This field is required.\"]}]}}"
六、Form類中的fields、widgets 簡單示例:
a、Form類:
from django import forms # 導入forms from django.forms import widgets # 導入插件 from django.forms import fields # 導入字段,之後對於像charField、EmailField等字段格式的處理不須要在經過form.進行定義了,而是經過fields進行定義 class FM(forms.Form): # 字段自己只作驗證 user = fields.CharField( error_messages={'required': '用戶名不能爲空.'}, # 定義錯誤信息的提示語,required爲定義輸入框爲空的提示語 # widget=widgets.Textarea(attrs={'class': 'c1'}), # 導入插件中的多行文本輸入,並定義樣式 label="用戶名", # 定義標籤名稱 ) pwd = fields.CharField( max_length=12, # 定義字符最大、最近小字符長度,及相應錯誤提示語 min_length=6, error_messages={'required': '密碼不能爲空.', 'min_length': '密碼長度不能小於6', "max_length": '密碼長度不能大於12'}, widget=widgets.PasswordInput(attrs={'class': 'c2'}) # 導入插件中的密碼非明文輸入,並定義樣式 ) email = fields.EmailField(error_messages={'required': '郵箱不能爲空.', 'invalid': "郵箱格式錯誤"}) # invalid定義輸入框無效是的提示語 f = fields.FileField() # 文件上傳 p = fields.FilePathField(path='app01') # 將路徑下的所有文件進行展現 city1 = fields.ChoiceField( # 單項選擇框 choices=[(0, '上海'), (1, '廣州'), (2, '東莞')] ) city2 = fields.MultipleChoiceField( # 多項選擇框 choices=[(0, '上海'), (1, '廣州'), (2, '東莞')] )
b.views:
from app01 import models def fm(request): if request.method == "GET": # 從數據庫中吧數據獲取到 dic = { "user": 'r1', 'pwd': 'password', 'email': 'email@163.com', 'city1': 1, 'city2': [1, 2] } obj = FM(initial=dic) # 初始化操做,經過字典形式傳遞默認值 return render(request, 'fm.html', {'obj': obj}) elif request.method == "POST": obj = FM(request.POST) r1 = obj.is_valid() if r1: # obj.cleaned_data print(obj.changed_data) # models.UserInf.objects.create(**obj.cleaned_data) else: # errors 繼承了ErrorDict類 print(obj.errors.as_json()) # print(obj.errors['user'][0]) return render(request, 'fm.html', {'obj': obj}) return redirect('http://www.ww.qq.com')
c、HTML:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/fm/" method="POST"> {% csrf_token %} <p>{{ obj.user.label}}{{ obj.user }} {{ obj.errors.user.0 }}</p> <!-- 相似於view視圖中的 obj.errors['user'][0]--> <p>{{ obj.pwd }} {{ obj.errors.pwd.0 }}</p> <p>{{ obj.email }}{{ obj.errors.email.0 }}</p> <p>{{ obj.f}}</p> <p>{{ obj.p}}</p> <p>{{ obj.city1}}</p> <p>{{ obj.city2}}</p> <input type="submit" value="提交" /> </form> </body> </html>