form組件(功能)html
生成html標籤前端
前端頁面是form類的對象生成的--->生成HTML標籤功能git
當用戶名和密碼輸入爲空或輸錯以後,頁面都會提示--->用戶提交校驗功能正則表達式
當用戶輸錯以後,再次輸入 上次的內容還保留在input框--->保留上次輸入內容數據庫
1.1 Form經常使用字段和插件---字段用於對用戶請求數據的驗證,插件用於自動生成HTMLdjango
initial 初始值,input框裏面的初始值 class LoginForm(forms.Form): username = forms.CharField( min_length = 8, label = '用戶名', initial = '張三')
error_messages重寫錯誤信息 class LoginForm(formS.Form): username = forms.CharField( min_length = 8, label = '用戶名:', initial = '張三', error_messages={ 'required':'不能爲空', 'invalid':'格式錯誤', 'min_length':'用戶名最短8位' })
Passwordsession
class LoginForm(forms.Form): password = forms.CharField( min_length = 6, label = '密碼', widget = forms.widgets.PasswordInput( attrs={'class':'c1'},render_value = True)) 這個密碼字段和其餘字段不同,默認在前端輸入數據錯誤的時候,點擊提交以後,默認不保存原來數據的,可是能夠經過這個render_value = True讓這個字段在前端保留用戶輸入的數據
radioSelect--->單radio值爲字符串 class LoginForm(forms.Form): username = forms.CharField( min_length = 8, label = '用戶名', initial = '張三', error_messages = { 'required':'不能爲空', 'invalid':'格式錯誤', 'min_length':'用戶名最短8位' } password = forms.CharField(label='密碼',min_length=6) gender = forms.fields.ChoiceField( choices = ((1,'男'),(2,'女'),) label='性別', initial = 2, widget = forms.widgets.RadioSelect())
單選Select class LoginForm(forms.Form): hobby = forms.fields.ChoiceField(###單選框用的是ChoiceField,而且插件用的是Select,否則驗證會報錯,Select a Valid choice的錯誤 choice = ((1,'抽菸'),(2,'喝酒'),(3,'燙頭')), label = '愛好', initial = 3, widget = forms.widgets.Select())
多選Select class LoginForm(forms.Form): hobby = forms.fields.MultipleChoiceField(---多選框用的是MultipleChoiceFiled,而且插件用的是SelectMultiple,否則驗證會報錯 choices = ((1,'籃球'),(2,'足球'),(3,'羽毛球'),), initial = 3, widget = forms.widgets.SelectMultiple() )
單選checkbox calss LoginForm(forms.Form): keep = forms.fields.ChoiceField( label = '是否記住密碼', initial = 'checked', widget = forms.widget.CheckboxInput() )
示例:函數
單選checkbox: class TestForm(forms.Form): keep = forms.Fields.ChoiceField( choices = (('True',1),('False',2),), label = '是否七天內自動登陸', initial = '1', widget = forms.widgets.CheakboxInput(),) 選中:'True' #form只是幫咱們作校驗,校驗選擇內容的時候,就是看在沒在咱們的choices裏面,裏面有這個值,表示合法,沒有就不合法 沒選中:'False' ---保存到數據庫裏面 keep:'True' if keep == 'True': session 設置有效期7天 else: pass
多選checkbox class LoginForm(forms.Form): hobby = forms.Fields.MultipleChoiceField( choices = ((1,'籃球'),(2,'足球'),(3,'羽毛球'),), label = '愛好', initial = 2, widget = forms.widgets.ChectboxSelectMultiple())
date類型 from django import forms class BookForm(forms.Form): date = forms.DateField(widget=widgets.TextInput(attrs={'type':'date'}))
choice字段注意事項:ui
在使用選擇標籤時,須要注意choices的選項能夠配置從數據庫中獲取,可是因爲是靜態字段 獲取的值沒法實時更新,須要重寫構造方法從而實現choice實時更新。插件
from django import forms class MyForm(forms.Form): user = forms.fields.ChoiceField( #choices = ((1,'上海'),(2,'北京'),), initial = 1, widget = forms.widgets.Select()) def __init__(self,*args,**kwargs): super(MyForm,self).__init__(*args,**kwargs) #self.field['user'].choices = ((1,'上海'),(2,'北京'),) 或者 #self.fields['user'].choices = models.Classes.objects.all().values_list('id','caption')
Form全部內置字段
Field required=True, 是否容許爲空 widget=None, HTML插件 label=None, 用於生成Label標籤或顯示內容 initial=None, 初始值 help_text='', 幫助信息(在標籤旁邊顯示) error_messages=None, 錯誤信息 {'required': '不能爲空', 'invalid': '格式錯誤'} validators=[], 自定義驗證規則 localize=False, 是否支持本地化 disabled=False, 是否能夠編輯 label_suffix=None Label內容後綴 CharField(Field) max_length=None, 最大長度 min_length=None, 最小長度 strip=True 是否移除用戶輸入空白 IntegerField(Field) max_value=None, 最大值 min_value=None, 最小值 FloatField(IntegerField) ... DecimalField(IntegerField) max_value=None, 最大值 min_value=None, 最小值 max_digits=None, 總長度 decimal_places=None, 小數位長度 BaseTemporalField(Field) input_formats=None 時間格式化 DateField(BaseTemporalField) 格式:2015-09-01 TimeField(BaseTemporalField) 格式:11:12 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 DurationField(Field) 時間間隔:%d %H:%M:%S.%f ... RegexField(CharField) regex, 自定製正則表達式 max_length=None, 最大長度 min_length=None, 最小長度 error_message=None, 忽略,錯誤信息使用 error_messages={'invalid': '...'} EmailField(CharField) ... FileField(Field) allow_empty_file=False 是否容許空文件 ImageField(FileField) ... 注:須要PIL模塊,pip3 install Pillow 以上兩個字典使用時,須要注意兩點: - form表單中 enctype="multipart/form-data" - view函數中 obj = MyForm(request.POST, request.FILES) URLField(Field) ... BooleanField(Field) ... NullBooleanField(BooleanField) ... ChoiceField(Field) ... choices=(), 選項,如:choices = ((0,'上海'),(1,'北京'),) required=True, 是否必填 widget=None, 插件,默認select插件 label=None, Label內容 initial=None, 初始值 help_text='', 幫助提示 ModelChoiceField(ChoiceField) ... django.forms.models.ModelChoiceField queryset, # 查詢數據庫中的數據 empty_label="---------", # 默認空顯示內容 to_field_name=None, # HTML中value的值對應的字段 limit_choices_to=None # ModelForm中對queryset二次篩選 ModelMultipleChoiceField(ModelChoiceField) ... django.forms.models.ModelMultipleChoiceField TypedChoiceField(ChoiceField) coerce = lambda val: val 對選中的值進行一次轉換 empty_value= '' 空值的默認值 MultipleChoiceField(ChoiceField) ... TypedMultipleChoiceField(MultipleChoiceField) coerce = lambda val: val 對選中的每個值進行一次轉換 empty_value= '' 空值的默認值 ComboField(Field) fields=() 使用多個驗證,以下:即驗證最大長度20,又驗證郵箱格式 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) MultiValueField(Field) PS: 抽象類,子類中能夠實現聚合多個字典去匹配一個值,要配合MultiWidget使用 SplitDateTimeField(MultiValueField) input_date_formats=None, 格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y'] input_time_formats=None 格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] FilePathField(ChoiceField) 文件選項,目錄下文件顯示在頁面中 path, 文件夾路徑 match=None, 正則匹配 recursive=False, 遞歸下面的文件夾 allow_files=True, 容許文件 allow_folders=False, 容許文件夾 required=True, widget=None, label=None, initial=None, help_text='' GenericIPAddressField protocol='both', both,ipv4,ipv6支持的IP格式 unpack_ipv4=False 解析ipv4地址,若是是::ffff:192.0.2.1時候,可解析爲192.0.2.1, PS:protocol必須爲both才能啓用 SlugField(CharField) 數字,字母,下劃線,減號(連字符) ... UUIDField(CharField) uuid類型 內置字段
RegexValidator驗證器 from django import forms class MyForm(forms.Form): user = forms.CharField( validators = [RegexValidator(r'^[0-9]+$','請輸入數字'), RegexValidator(r'^159[0-9]+$','數字必須以159開頭')],)
自定義驗證器
import re from django import forms 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(forms.Form): title = fields.CharField(max_length=20, min_length=5, error_message{ 'required':'標題不能爲空', 'min_length':'標題最少爲5個字符', 'max_length':'標題最多爲20個字符' }, widget = forms.widgets.TextInput(attrs={'class':'form-control','placeholder':'標題5-20個字符'}))
#使用自定義驗證規則 phone = fields.CharField(validators=[mobile_validate,], error_messages={ 'required':'手機不能爲空' }, widget = forms.widgets.TextInput(attrs={'class':'form-control','placeholder':u'手機號碼'})), email = fields.EmailField(required=False,error_message={ 'required':u'郵箱不能爲空','invalid':u'郵箱格式錯誤' }, widget = forms.widgets.TextInput(attrs={'class':'form-control','placeholder':u'郵箱'}))
Hook鉤子方法
1 局部鉤子(在Form類中定義clean_字段名()方法,就能實現對特定字段進行校驗)
from django import forms class LoginForm(forms.Form): username = forms.CharField( min_length = 8, label='用戶名', initial='張三', error_messages={ 'required':'不能爲空', 'invalid':'格式錯誤', 'min_length':'用戶名最短8位' }, widget=forms.widgets.TextInput(attrs={'class':'form-control'})) #定義局部狗子,用來校驗username字段,以前的校驗規則還在,給你提供了一個添加一些校驗功能的鉤子 def clean_username(self): value = self.cleaned_data.get('username') if '666' in value: raise ValidationError('光喊666是不行的') else: return value
4.2 全局鉤子
咱們在Form類中定義clean()方法,就可以實現對字段進行全局校驗,字段所有驗證完,局部鉤子也所有執行完以後,執行這個全局鉤子校驗 class LoginForm(forms.Form): password = forms.CharField( min_length=6, label = '密碼', widget = forms.widgets.PasswordInput(attrs=('class':'form-control'),render_value=True)) re_password = forms.CharField( min_length = 6, label = '確認密碼', widget = forms.widgets.PasswordInput(attrs={'class':'form-control'},render_value=True)) 定義全局的鉤子,用來校驗密碼和確認密碼字段是否相同,執行全局鉤子的時候,cleaned_data裏面確定是有了經過前面驗證的全部數據 def clean(self): password_value = self.cleaned_data.get('password') re_password_value = self.cleaned_data.get('re_password') if password_value == re_password_value: return self.cleaned_data #全局鉤子要返回全部的數據 else: self.add_error('re_password', '兩次密碼不一致') #在re_password這個字段的錯誤列表中加上一個錯誤,而且clean_data裏面會自動清除這個re_password的值,因此打印clean_data的時候會看不到它 raise ValidationError('兩次密碼不一致')