django的Form二

views.py

from django import forms

# class FM(forms.Form):
#     #字段本身只做驗證
#     username = forms.CharField(error_messages={'required': '用戶名不能為空'})
#     password = forms.CharField(
#         max_length=12,
#         min_length=6,
#         error_messages={'required': '密碼不能為空', 'min_length': '密碼小于6', 'max_length': '密碼大于12'}
#     )
#     email = forms.EmailField(error_messages={'required': '郵箱不能為空', 'invalid': '郵箱格式錯誤'})

以后最好用下面這種寫法:

from django.forms import fields
from django.forms import widgets
from django import forms

#  widget是一個插件,生成html格式
#  字段本身只做驗證
#  forms 改為 fields
#  用widget可以自定義html,并且還可以添加html的屬性

# username,password,email必須與template的form 中name屬性字段一致
class FM(forms.Form):    
    username = fields.CharField(error_messages={'required': '用戶名不能為空'}, widget=widgets.Textarea(attrs={'class': 'c1'}))
    password = fields.CharField(
        max_length=12,
        min_length=6,
        error_messages={'required': '密碼不能為空', 'min_length': '密碼小于6', 'max_length': '密碼大于12'},
        widget=widgets.PasswordInput(attrs={'class': 'c3'})
    )
    email = fields.EmailField(error_messages={'required': '郵箱不能為空', 'invalid': '郵箱格式錯誤'})

自定義驗證
方式一:

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] 


Django的Form主要具有一下幾大功能:
?生成HTML標簽
?驗證用戶數據(顯示錯誤信息)
?HTML Form提交保留上次提交數據
?初始化頁面顯示內容

創建Form類時,主要涉及到 【字段】 和 【插件】,字段用于對用戶請求數據的驗證,插件用于自動生成HTML;

1、Django內置字段如下:

Field 
    required=True,               是否允許為空 
    widget=None,                 HTML插件 
    label=None,                  用于生成Label標簽或顯示內容 
    initial=None,                初始值 
    help_text='',                幫助信息(在標簽旁邊顯示) 
    error_messages=None,         錯誤信息 {'required': '不能為空', 'invalid': '格式錯誤'} 
    show_hidden_initial=False,   是否在當前插件后面再加一個隱藏的且具有默認值的插件(可用于檢驗兩次輸入是否一直) 
    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類型 
    ...  

Django內置插件:

TextInput(Input) 
NumberInput(TextInput) 
EmailInput(TextInput) 
URLInput(TextInput) 
PasswordInput(TextInput) 
HiddenInput(TextInput) 
Textarea(Widget) 
DateInput(DateTimeBaseInput) 
DateTimeInput(DateTimeBaseInput) 
TimeInput(DateTimeBaseInput) 
CheckboxInput 
Select 
NullBooleanSelect 
SelectMultiple 
RadioSelect 
CheckboxSelectMultiple 
FileInput 
ClearableFileInput 
MultipleHiddenInput 
SplitDateTimeWidget 
SplitHiddenDateTimeWidget 
SelectDateWidget 
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容