您好,登錄后才能下訂單哦!
本文實例講述了Python Web框架之Django框架Form組件用法。分享給大家供大家參考,具體如下:
Form簡介
在HTTP中,表單(form標簽),是用來提交數據的,其action屬性說明了其傳輸數據的方法:如何傳、如何接收。
訪問網站時,表單可以實現客戶端與服務器之間的通信。例如查詢,就用到了表單(其屬性中,action=get)。
再比如說注冊與登陸,也是要用到表單的。但這里由于涉及到隱私問題,需要保證數據傳輸的安全性,因此其傳輸方法就應當使用post而非get。
總之,對客戶端來說,表單就是用來向服務器提交數據的;
而對服務器來說,表單就是你提供給客戶端的發送信息的渠道,你需要對用戶發送來的信息進行處理和響應,以達到頁面的交互。
Django Form的功能
Django Form驗證流程
用于驗證用戶請求數據合法性的一個組件
如果沒有Form就得繁瑣地用正則表達式了
a. 用戶提交數據的驗證
1、創建模版 class LoginForm(forms.Form):...
2、將請求交給模版,創建一個對象 obj = LoginForm(request.POST)
3、進行驗證 obj.is_valid()
4、獲取正確信息 obj.clean()
5、獲取錯誤信息 obj.errors
b. 錯誤信息提示
Form提交,刷新頁面的特性,模版對象內部值豐富,再顯示時,值和錯誤信息都有
c. 保留上一次提交的數據
1、自動生成html標簽
2、保留上一次提交的數據
Form的創建
from django.shortcuts import render, redirect from django import forms #這里為了簡單,把form類寫到視圖函數 # 模版 class LoginForm(forms.Form): # 模版中的元素 user = forms.CharField(min_length=6,error_messages={"required": '用戶名不能為空','min_length': '用戶名長度不能小6'}) email = forms.EmailField(error_messages={"required": '郵箱不能為空','invalid': '郵箱格式錯誤'}) def login(request): if request.method == "GET": # 數據庫中獲取 obj = LoginForm() return render(request,'login.html',{'oo': obj}) elif request.method == "POST": """ obj = LoginForm(request.POST) # 驗證 status = obj.is_valid() print(status) value_dict = obj.clean() 驗證成功的值,輸入格式正確的拿到了 print(value_dict) # error_obj = obj.errors error_obj = obj.errors.as_json() print(error_obj) code定義錯誤信息 """ obj = LoginForm(request.POST) if obj.is_valid(): value_dict = obj.clean() print(value_dict) # create(**value_dict) else: # 封裝了所有的錯誤信息 # error_obj=obj.errors # print(obj.errors['email'][0],type(error_obj['email']) # print(obj.errors['email'][0],type(error_obj['email'][0]) # print(obj.errors["user"][0]) # print(type(error_obj)) from django.forms.utils import ErrorDict pass return render(request, 'login.html',{'oo': obj})
當然你也可以在app里創建form.py文件,在里面創建類:
下文將使用這個文件。
from django import forms as DForms from django.forms import fields from django.forms import widgets from django.core.validators import RegexValidator class DetailForm(DForms.Form): user1 = fields.CharField() #默認input框,可以改成select,radio等 user2 = fields.CharField(widget=widgets.TextInput) user4 = fields.IntegerField() # 字符串 user3 = fields.ChoiceField(choices=[(1, 'SH'), (2, 'BJ'), ]) user5 = fields.CharField( widget=widgets.Select(choices=[(1, 'SH'), (2, 'BJ'), ]) ) user6 = fields.IntegerField( widget=widgets.Select(choices=[(1, 'SH'), (2, 'BJ'), ]) ) user7 = fields.IntegerField( widget=widgets.RadioSelect(choices=[(1, 'SH'), (2, 'BJ'), ]) ) #{'user1': '11', 'user2': '22', 'user4': 33, 'user3': '1', 'user5': '2', 'user6': 1, 'user7': 2}
視圖函數:
from django.shortcuts import render, redirect from app01 import forms def detail(request): obj = forms.DetailForm(request.POST) obj.is_valid() print(obj.clean()) return render(request,'detail.html', {'obj': obj})
生成HTML:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/detail.html" method="POST"> {{ obj.user1 }} {{ obj.user2 }} {{ obj.user3 }} {{ obj.user4 }} {{ obj.user5 }} {{ obj.user6 }} {{ obj.user7 }} <input type="submit" value="提交"/> </form> </body> </html>
常用HTML標簽:
<form method="POST" enctype="multipart/form-data"> {% csrf_token %} {{ form.xxoo.label }} {{ form.xxoo.id_for_label }} {{ form.xxoo.label_tag }} {{ form.xxoo.errors }} <p>{{ form.user }} {{ form.user.errors }}</p> <input type="submit" /> </form>
運行后后臺返回結果:
#{'user1': '11', 'user2': '22', 'user4': 33, 'user3': '1', 'user5': '2', 'user6': 1, 'user7': 2}
下面將講解為什么是這個結果
Django的Form的實現步驟:
a. 創建一個驗證用戶請求的模板包含:
類:模版,到底驗證幾個
字段:用于驗證用戶某個字段
插件:user = forms.CharField(..,widget=Input框)
Django內置字段如下:
1,字段核心參數
每個字段類的構造函數至少接受這些參數。有些字段類接受額外的、字段特有的參數,但以下參數應該總是能接受:
Field.required
默認情況下,每個字段 類都假設必需有值,所以如果你傳遞一個空的值 —— 不管是None 還是空字符串(“”) —— clean() 將引發一個ValidationError 異常。
Field.label
正如在前面“輸出表單為HTML”中解釋的,字段默認label 是通過將字段名中所有的下劃線轉換成空格并大寫第一個字母生成的。如果默認的標簽不合適,可以指定label。
Field.label_suffix
label_suffix 參數讓你基于每個字段覆蓋表單的label_suffix。
Field.initial
initial 參數讓你指定渲染未綁定的表單中的字段時使用的初始值。
Field.widget
widget 參數讓你指定渲染表單時使用的Widget 類。更多信息參見Widgets。
Field.help_text
help_text 參數讓你指定字段的描述文本。如果提供help_text,在通過表單的便捷方法(例如,as_ul())渲染字段時,它將緊接著字段顯示。
Field.error_messages
error_messages 參數讓你覆蓋字段引發的異常中的默認信息。傳遞的是一個字典,其鍵為你想覆蓋的錯誤信息。
Field.validators
validators 參數讓你可以為字段提供一個驗證函數的列表。
Field.localize
localize 參數啟用表單數據的本地化,包括輸入和輸出。
Field.has_changed()
has_changed() 方法用于決定字段的值是否從初始值發生了改變。返回True 或False。
2,內建字段
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 是否移除用戶輸入空白
可選參數:max_length, min_length
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
MultipleChoiceField(**kwargs)
TypedMultipleChoiceField(**kwargs)
就像MultipleChoiceField,除了TypedMultipleChoiceField需要兩個額外的參數,coerce和empty_value。
TypedChoiceField(ChoiceField)
coerce = lambda val: val 對選中的值進行一次轉換
empty_value= '' 空值的默認值
ImageField(**kwargs)
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=''
FileField(**kwargs)
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類型
3.處理關系字段
兩個字段可用于表示模型之間的關系:ModelChoiceField和ModelMultipleChoiceField。這兩個字段都需要單個queryset參數,用于創建字段的選擇。在表單驗證時,這些字段將把一個模型對象(在ModelChoiceField的情況下)或多個模型對象(在ModelMultipleChoiceField的情況下)放置到cleaned_data表單的字典。
對于更復雜的用法,可以在聲明表單字段時指定queryset=None,然后在窗體的init()方法中填充queryset:
ModelChoiceField(**kwargs)
ModelMultipleChoiceField(**kwargs)
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
# 單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 # )
在使用選擇標簽時,需要注意choices的選項可以從數據庫中獲取,但是由于是靜態字段 ***獲取的值無法實時更新***,那么需要自定義構造方法從而達到此目的。
如果內建的字段不能滿足你的需求,你可以很容易地創建自定義的字段。你需要創建django.forms.Field 的一個子類。它只要求實現一個clean() 方法和接收上面核心參數的init() 方法(required, label, initial, widget, help_text)。
#方法一: from app01 import models class DBForm(DForms.Form): host = fields.CharField() host_type = fields.IntegerField( widget=widgets.Select(choices=[]) ) def __init__(self,*args, **kwargs): # 執行父類的構造方法 super(DBForm,self).__init__(*args, **kwargs) self.fields['host_type'].widget.choices = models.UserType.objects.all().values_list('id','caption') #方法二:使用django提供的ModelChoiceField和ModelMultipleChoiceField字段來實現 from django import forms from django.forms import fields from django.forms import widgets from django.forms import models as form_model from django.core.exceptions import ValidationError from django.core.validators import RegexValidator class FInfo(forms.Form): authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())
自定義Form驗證規則:
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開頭')], ) # 方法二 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('手機號碼格式錯誤') phone = fields.CharField(validators=[mobile_validate, ], error_messages={'required': '手機不能為空'}, 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
希望本文所述對大家基于Django框架的Python程序設計有所幫助。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。