1. 程式人生 > >Django的form元件

Django的form元件

1、Form元件簡介

2、Form元件的使用

2.1、Form元件的引用

from django import forms

2.2、定義一個form類

class RegForm(forms.Form):
    ser = forms.CharField()
    pwd = forms.CharField()
    email = forms.EmailField()    

2.3、例項化

form_obj = RegForm()

2.4、生產HTML

2.4.1、方式一

{{ form_obj.as_p }}

2.4.2、方式二

{{ form_obj.pwd.label }}
{{ form_obj.pwd }}

2.5、提交資料校驗

form_obj = RegForm(request.POST)
form_obj.is_valid()

7、Form中Field的型別

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型別 ...

8、Form中內建外掛

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

 

9、常用選擇外掛

# 單radio,值為字串

# user = fields.CharField(

#     initial=2,

#     widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))

# )

# 單radio,值為字串 # user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), # initial=2, # widget=widgets.RadioSelect # )
# 單select,值為字串 # user = fields.CharField( # initial=2, # widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)) # )
# 單select,值為字串 # user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), # initial=2, # widget=widgets.Select # ) # 多選select,值為列表 # user = fields.MultipleChoiceField( # choices=((1,'上海'),(2,'北京'),), # initial=[1,], # widget=widgets.SelectMultiple # ) # 單checkbox # user = fields.CharField( # widget=widgets.CheckboxInput() # ) # 多選checkbox,值為列表 # user = fields.MultipleChoiceField( # initial=[2, ], # choices=((1, '上海'), (2, '北京'),), # widget=widgets.CheckboxSelectMultiple # )

10、自定義驗證規則

 10.1、方式一

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開頭')],
    )

10.2、方式二

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'郵箱'}))

10.3、方式三:自定義方法

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

10.4、方式四:同時生成多個標籤進行驗證

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]