Django基礎之Form表單驗證

Form表單驗證

1.建立Form類(本質就是正則表達式的集合)

from django.forms import Form
from django.forms import fields
from django.forms import widgets
from Mybbs.models import *
import re

class UserForm(Form):
    username = fields.CharField(
        required=True,
        error_messages={'required':'用戶名不能爲空'},
        widget=widgets.TextInput(attrs={'class':'form-control'})
    )

    password = fields.CharField(
        required=True,
        error_messages={'required': '密碼不能爲空','invalid':'密碼格式錯誤'},
        widget = widgets.TextInput(attrs={'class': 'form-control'})
    )

    ut_id = fields.ChoiceField(
        choices=[],
        widget=widgets.Select(attrs={'class':'form-control'})
    )

    role_id = fields.MultipleChoiceField(
        choices=[],
        widget=widgets.SelectMultiple(attrs={'class':'form-control'})
    )

建立自定義類繼承Form,類屬性最好與數據庫字段名稱相同:html

required:不能爲空
error_messages:錯誤信息
widget:渲染方式前端

# 若是須要讀庫的內容,則應該放入 類初始化方法中,否則數據庫有更新,卻更新不到頁面,
# 由於類屬性 只有在第一次生成的時候執行,而 初始化方法 在每次類被調用的時候都執行,能拿到第一手資料
def __init__(self, *args, **kwargs):
    super(UserForm, self).__init__(*args, **kwargs)
    # self.fields已經有全部拷貝的字段
    self.fields['ut_id'].choices = models.UserType.objects.values_list('id', 'title')
    self.fields['role_id'].choices = models.Role.objects.values_list('id', 'caption')

2.前端生成HTML

<form method="POST" novalidate>
	{% csrf_token %}
	<!--{{ form.as_p }}  生成form中全部的html標籤 -->
	<p>
		用戶名: {{ form.username }} {{ form.errors.username.0 }}
	</p>
	<p>
		密碼: {{ form.password }}  {{ form.errors.password.0 }}
	</p>
	<p>
		用戶類型: {{ form.ut_id }}  {{ form.errors.ut_id.0 }}
	</p>
	<p>
		角色: {{ form.role_id }}  {{ form.errors.role_id.0 }}
	</p>

	<input type="submit" value="提交" />
</form>

 novalidate:禁止瀏覽器彈出的錯誤python

3.帶默認值的好HTML標籤:編輯界面

class EditUserView(AuthView,View):
    
    def get(self, request, pk):
        obj = models.UserInfo.objects.filter(id=pk).first()
        role_id_list = obj.rl.values_list('id')
        v = list(zip(*role_id_list))[0] if role_id_list else []
        form = UserForm(initial={'username': obj.username, 'password': obj.password, 'ut_id': obj.ut_id,'role_id':v})
        return render(request,'edit_user.html',{'form':form})

    def post(self,request,pk):
        form = UserForm(data=request.POST)
        if form.is_valid():
            # # {'username': 'xxxxx', 'password': 'xxxxx', 'ut_id': '1',role_id:}
            role_id = form.cleaned_data.pop('role_id')
            # 用戶表更新
            query = models.UserInfo.objects.filter(id=pk)
            query.update(**form.cleaned_data)
            obj = query.first()
            obj.rl.set(role_id)

            return redirect('/users.html')
        else:
            print(form.errors)
            return render(request, 'edit_user.html', {'form': form})

Form類

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

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

 2.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

 實例:正則表達式

 1 - 經常使用插件
 2             
 3             class RegisterForm(Form):
 4                 name = fields.CharField(
 5                     widget=widgets.TextInput(attrs={'class': 'c1'})
 6                 )
 7                 email = fields.EmailField(
 8                     widget=widgets.EmailInput(attrs={'class':'c1'})
 9                 )
10                 phone = fields.CharField(
11                     widget=widgets.Textarea(attrs={'class':'c1'})
12                 )
13                 pwd = fields.CharField(
14                     widget=widgets.PasswordInput(attrs={'class':'c1'})
15                 )
16                 pwd_confirm = fields.CharField(
17                     widget=widgets.PasswordInput(attrs={'class': 'c1'})
18                 )
19                 # 單選:select
20                 # city = fields.ChoiceField(
21                 #     choices=[(0,"上海"),(1,'北京')],
22                 #     widget=widgets.Select(attrs={'class': 'c1'})
23                 # )
24                 # 多選:select
25                 # city = fields.MultipleChoiceField(
26                 #     choices=[(1,"上海"),(2,'北京')],
27                 #     widget=widgets.SelectMultiple(attrs={'class': 'c1'})
28                 # )
29                 
30                 # 單選:checkbox
31                 # city = fields.CharField(
32                 #     widget=widgets.CheckboxInput()
33                 # )
34 
35                 # 多選:checkbox
36                 # city = fields.MultipleChoiceField(
37                 #     choices=((1, '上海'), (2, '北京'),),
38                 #     widget=widgets.CheckboxSelectMultiple
39                 # )
40 
41                 # 單選:radio
42                 # city = fields.CharField(
43                 #     initial=2,
44                 #     widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
45                 # )
46         
47             注意:寫默認值時,多選值對應列表
48             
49             # form = RegisterForm(initial={'city':[1,2],'name':'alex'})
50             form = RegisterForm()
51 
52 實例
View Code
相關文章
相關標籤/搜索