Django--2、form表單


django中定義form表單的優勢

  • HTML中提交后,若數據出現錯誤,返回的頁面中仍然可以保留之前輸入的數據。
  • 通過校驗規則可以方便的限制字段條件並校驗。

在Django中建個form表單

先要確定給什么表單構建。

使用form類

from django import forms
 
class NameForm(forms.Form):
    your_name = forms.CharField(label='Your name', max_length=100)
#定義了一個form類,
  
字段最大長度max_length的定義,做了兩件事,
1:在HTMLinput上加了 maxlength="100"(瀏覽器會進行限制)
2:當Django收到瀏覽器發來的表單后,驗證數據長度

渲染到HTML后:

<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" maxlength="100">

注:不包含form標簽和提交按鈕,需要自己在HTML中寫好。

is_valid

為所有字段進行驗證,條件驗證通過將:返回TRUE,將表單數據放到cleaned_data屬性中。

視圖

表單數據要通過視圖處理,一般和發布的是同一個,可以重用相同邏輯。

from django.shortcuts import render
from django.http import HttpResponseRedirect

from .forms import NameForm

def get_name(request):
    # if this is a POST request we need to process the form data
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = NameForm(request.POST)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            return HttpResponseRedirect('/thanks/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = NameForm()

    return render(request, 'name.html', {'form': form})
#如果訪問視圖的是一個GET 請求,它將創建一個空的表單實例並將它放置到要渲染的模板的上下文中。

#如果表單的提交使用POST 請求,那么視圖將再次創建一個表單實例並使用請求中的數據填充它:form = NameForm(request.POST)。這叫做”綁定數據至表單“(它現在是一個綁定的表單)。

#調用表單的is_valid()方法;如果它不為True,我們將帶着這個表單返回到模板。這時表單不再為空(未綁定),所以HTML 表單將用之前提交的數據填充,然后可以根據要求編輯並改正它。
#如果is_valid()True,我們將能夠在cleaned_data 屬性中找到所有合法的表單數據。在發送HTTP 重定向給瀏覽器告訴它下一步的去向之前,我們可以用這個數據來更新數據庫或者做其它處理。

HTML模板

最簡單的:

<form action="/your-name/" method="post"> {% csrf_token %}{{ form }} <input type="submit" value="Submit" /> </form> #{{ form }}即服務端對應的表單 注:Django 原生支持一個簡單易用的跨站請求偽造的防護。當提交一個啟用CSRF 防護的POST 表單時,你必須使用上面例子中的csrf_token 模板標簽。 

Django Form類

綁定的和未綁定的表單實例

  • 未綁定的沒有關聯數據。渲染時為空或默認值
  • 綁定的包含提交來的數據,可檢驗數據是否合法。若不合法,將包含內聯的錯誤信息,返回。

字段詳解

from django import forms
class RegForm(forms.Form):
    u = forms.CharField(max_length=10
    ,error_messages={"max_length":"最長10字符""required":"字段不能為空"})
    p = forms.CharField(mix_length=8,
    widget=widgets.PasswordInput(attrs={"placeholder":"password"})
    gender = forms.CharField(initial=2,
    widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)))
    email = forms.EmailField()
    is_married = forms.BooleanField(required=False)
)

widgets

對應HTML表單的widget(type的數據類型格式)
不同字段默認不同widget,默認charfield是textinput widget。在HTML 中生成一個<input type="text">。

字段的數據

提交通過is_valid驗證后,驗證后的表單數據將存放於form.cleaned_data字典中(數據類型轉換已好)

使用表單模板

若在字段屬性中設置label,則會渲染成對於<label>/<input> 對。

表單渲染的選項

輸出選項:

{{ form.as_table }} 以表格的形式將它們渲染在<tr> 標簽中
{{ form.as_p }} 將它們渲染在<p> 標簽中
{{ form.as_ul }} 將它們渲染在<li> 標簽中

注意,若用tableul。必須自己提供<table> <ul> 元素。

手動渲染

手工來做允許重新對字段排序。每個字段都是表單的一個屬性。 使用{{ form.name_of_field }} 訪問

<div class="fieldWrapper">
    {{ form.Username.errors }}
    {{ form.Username.label_tag }}
    {{ form.Username }}
</div>

表單的錯誤信息及渲染

type(registerForm.errors)
  #<class 'django.forms.utils.ErrorDict'> 錯誤清單,會渲染成ul
type(registerForm.errors["username"])
  #<class 'django.forms.utils.ErrorList'>

form組件的鈎子

即對接收到的form數據做自定義規則的判斷。

定義Django的form時:
  
from django import forms

class RegForm(forms.Form):
    username = forms.CharField(label='username', max_length=100)
    password = forms.CharField(label='password', max_length=100)
    repeat_password = forms.CharField(label='repeat_password',,max_length=100)
#鈎子函數為對應字段添加判斷條件。做最小長度判斷 def clean_username(self): if len(self.cleaned_data.get("username"))>5: print(self.cleaned_data.get("password")) return self.cleaned_data.get("username") def clean_password(self): pass #全局鈎子函數。判斷兩次密碼輸入是否一致 def clean(self): if self.cleaned_data["password"] == self.cleaned_data["repeat_password"]: return self.cleaned_data

———————————————————————————————————————————————————————————————————————————————————————

def foo(request):


    if request.method=="POST":

        regForm=RegForm(request.POST)

        if regForm.is_valid():
            pass
            # 可用數據: regForm.cleaned_data,
            # 將數據插入數據庫表中


        else:
            pass
            # 可用數據: regForm.errors
            # 可以利用模板渲染講errors嵌套到頁面中返回
            # 也可以打包到一個字典中,用於ajax返回

    else:
        regForm=RegForm()
    return render(request,"register.html",{"regForm":regForm})

實例化時: self.fields={ "username":"字段規則對象", "password":"字段規則對象",
       "
repeat_password":"字段規則對象",
        }


    is_valid:

        self._errors = {}
        self.cleaned_data = {}


        #局部鈎子:

        for name, field in self.fields.items():
              try:

                    value = field.clean(value)
                    self.cleaned_data[name] = value
                    if hasattr(self, 'clean_%s' % name):
                        value = getattr(self, 'clean_%s' % name)()
                        self.cleaned_data[name] = value
              except ValidationError as e:
                    self.add_error(name, e)

        # 全局鈎子:

        self.clean()     # def self.clean():return self.cleaned_data

        return  not self.errors    # True或者False

 

Filed字段通用配置參數如下

    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內容后綴
 
View Code

 

不同字段的配置參數

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類型
    ...
View Code

 

widget的可配置字段插件(HTML中input的type值)
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
View Code

 

widget常用的選擇插件

# 單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
# )
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM