Python學習 Day 069 - Django - form元件
阿新 • • 發佈:2018-12-12
主要內容:
- 1.form元件概述
- 2.示例:使用form元件實現註冊功能
- 3.form相關
1. form元件概述
(1)form元件
- 當在HTML頁面中利用form表單向後端提交資料時,都會寫一些獲取使用者輸入的標籤並且用form標籤把它們包起來。
- 與此同時我們在好多場景下都需要對使用者的輸入做校驗,比如校驗使用者是否輸入,輸入的長度和格式等正不正確。如果使用者輸入的內容有錯誤就需要在頁面上相應的位置顯示對應的錯誤資訊.。
(2) form元件功能
- 生成頁面可用的HTML標籤
- 對使用者提交的資料進行校驗
- 保留上次輸入內容
2.示例:使用form元件實現註冊功能
- forms.py
from django import forms from django.core.exceptions import ValidationError from django.core.validators import RegexValidator def check(value): if '蒼老師' in value: raise ValidationError('敏感詞彙,不能使用') #按照django form元件的要求自己寫一個類 class RegForm(forms.Form): user = forms.CharField( label
- views.py
from django.shortcuts import render,HttpResponse from app01.forms import RegForm #寫檢視函式 def register(request): # 例項化一個form物件 form_obj = RegForm() #判斷請求方式為POST if request.method == 'POST': #例項化form物件的時候,把post提交過來的資料直接傳進去 form_obj = RegForm(data=request.POST) #呼叫form_obj校驗資料的方法 if form_obj.is_valid(): #將資料儲存到資料庫中 #cleand_data 表示經過校驗的合格的資料 return HttpResponse('註冊成功') return render(request,'register.html',{'form_obj':form_obj})
- html 程式碼
<body> <form action="" method ='post' novalidate> {% csrf_token %} {# {{ form_obj.as_p }}#} {# {{ form_obj.errors }}#} <P> <label for="{{ form_obj.user.id_for_label }}">{{ form_obj.user.label }}</label> {{ form_obj.user }} {{ form_obj.user.errors.0}} </P> <P> <label for="{{ form_obj.email.id_for_label }}">{{ form_obj.email.label }}</label> {{ form_obj.email }} {{ form_obj.email.errors.0}} </P> <P> <label for="{{ form_obj.pwd.id_for_label }}">{{ form_obj.pwd.label }}</label> {{ form_obj.pwd }} {{ form_obj.pwd.errors.0}} </P> <P> <label for="{{ form_obj.re_pwd.id_for_label }}">{{ form_obj.re_pwd.label }}</label> {{ form_obj.re_pwd }} {{ form_obj.re_pwd.errors.0}} </P> <P> <label for="{{ form_obj.gender.id_for_label }}">{{ form_obj.gender.label }}</label> {{ form_obj.gender }} {{ form_obj.gender.errors.0}} </P> <P> <label for="{{ form_obj.phone.id_for_label }}">{{ form_obj.phone.label }}</label> {{ form_obj.phone }} {{ form_obj.phone.errors.0}} </P> <P> <label for="{{ form_obj.hobby.id_for_label }}">{{ form_obj.hobby.label }}</label> {{ form_obj.hobby }} {{ form_obj.hobby.errors.0}} </P> <button>註冊</button> </form>
3. form相關
3.1常用欄位與外掛
(1)radioSelect,單radio值為字串
gender = forms.fields.ChoiceField( choices=((1, "男"), (2, "女"), (3, "保密")), label="性別", initial=3, widget=forms.widgets.RadioSelect() )
(2) 單選Selsect
hobby = forms.fields.ChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"), ), label="愛好", initial=3, widget=forms.widgets.Select() )
(3)多選Select
hobby = forms.fields.MultipleChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"), ), label="愛好", initial=[1, 3], widget=forms.widgets.SelectMultiple() )
(4)單選checkbox
keep = forms.fields.ChoiceField( label="是否記住密碼", initial="checked", widget=forms.widgets.CheckboxInput() )
關於choice的注意事項:
在使用選擇標籤時,需要注意choices的選項可以從資料庫中獲取,但是由於是靜態欄位 ***獲取的值無法實時更新***,那麼需要自定義構造方法從而達到此目的。
from django.forms import Form from django.forms import widgets from django.forms import fields class MyForm(Form): user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), initial=2, widget=widgets.Select ) def __init__(self, *args, **kwargs): super(MyForm,self).__init__(*args, **kwargs) # self.fields['user'].choices = ((1, '上海'), (2, '北京'),) # 或 self.fields['user'].choices = models.Classes.objects.all().values_list('id','caption')方式一
from django import forms from django.forms import fields from django.forms import models as form_model class FInfo(forms.Form): authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) # 多選 # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all()) # 單選方式二
3.2 django 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型別 Django Form內建欄位form所有內建欄位
3.3 校驗
(1)內建校驗
#例如 required=True,min_length=8,max_length=12,
(2)自定義校驗
- 定義函式
from django.core.exceptions import ValidationError #可以自定義一個函式 def check(value): if 'alex' in value: raise ValidationError('敏感詞彙,不符合社會職業核心價值觀') #在欄位中 validators =[] 中新增函式名的方式 validators=[check]
- 引入
from django.core.validators import RegexValidator #同樣在欄位中的validators =[]中新增 validators=[RegexValidator(r'^1[3-9]\d{9}$', '格式不正確')] #關於 RegexValidator 一般寫正則 ,以及錯誤message就可以 class RegexValidator(object): regex = '' message = _('Enter a valid value.') code = 'invalid' inverse_match = False flags = 0 def __init__(self, regex=None, message=None, code=None, inverse_match=None, flags=None):