一、Form組件介紹
1、Form組件可以做的幾件事情
1、用戶請求數據驗證
2、自動生成錯誤信息
3、打包用戶提交的正確信息
4、如果其中有一個錯誤了,其他的正確這,保留上次輸入的內容
5、自動創建input標籤並可以設置樣式
2、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, #最小值 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': '...'} FileField(Field) allow_empty_file = False #是否允許空文件 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 = '' # 空值的默認值 TypedMultipleChoiceField(MultipleChoiceField) coerce = lambda val: val #對選中的每一個值進行一次轉換 empty_value = '' #空值的默認值 ComboField(Field) fields = () #使用多個驗證,如下:即驗證最大長度20,又驗證郵箱格式 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(), ]) 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才能啓用
3、常用選擇插件
# 單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 )
二、表單渲染註冊頁面
views.py文件內容:
from django.shortcuts import render,HttpResponse from django import forms from django.forms import widgets class UserForm(forms.Form): user=forms.CharField(label="用戶名", min_length=5, error_messages={"required":"不能爲空","min_length":"最小長度不能小於5"}, widget=widgets.TextInput(attrs={"class":"form-control"}) ) tel=forms.CharField(label="手機號",max_length=8, widget=widgets.TextInput(attrs={"class":"form-control"})) email=forms.EmailField(label="郵箱", widget=widgets.TextInput(attrs={"class":"form-control"})) def reg(request): if request.method=="POST": #form=UserForm({"user":"alex999","tel":'123',"email":"111","123":123}) form=UserForm(request.POST) if form.is_valid(): print("====>",form.cleaned_data) # 校驗成功的字段{"user":"alex999","tel":'123'} print("====>",form.errors) # 校驗失敗的字段 return HttpResponse("添加成功") else: # print("---->", form.cleaned_data) # # print("---->", type(form.errors)) # <class 'django.forms.utils.ErrorDict'> # print("---->", type(form.errors["user"])) # # print("---->", form.errors["user"][0]) # return render(request, 'reg.html',{"form":form}) form=UserForm() return render(request,'reg.html',{"form":form})
reg.html文件內容:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> <style> span{ color: red!important; } </style> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> {#####################################方案一:#######################################} <div> <div> <div class="col-md-6 col-md-offset-3"> <form action="" method="post" novalidate> {% csrf_token %} {% for filed in form %} <div> <label for="">{{ filed.label }}</label> {{ filed }} </div> {% endfor %} <input type="submit"> </form> </div> </div> </div> {#####################################方案二:#######################################} <div> <div> <div class="col-md-6 col-md-offset-3"> <form action="" method="post" novalidate> {% csrf_token %} <div> 用戶名: {{ form.user }} </div> <div> 郵箱: {{ form.email }} </div> <div> 手機號: {{ form.tel }} </div> <input type="submit"> </form> </div> </div> </div> {#####################################方案三:#######################################} <div> <div> <div class="col-md-6 col-md-offset-3"> <form action="" method="post" novalidate> {% csrf_token %} {{ form.as_p }} <input type="submit"> </form> </div> </div> </div> </body> </html>
三、示例
views.py文件內容:
from django.shortcuts import render,redirect from app01 import models from django.forms import Form from django.forms import fields from django.forms import widgets class TeacherForm(Form): #必須繼承Form username = fields.CharField( required=True, #必填字段 error_messages={"required":"用戶名不能爲空!!"}, #顯示中文錯誤提示 widget=widgets.TextInput(attrs={"placeholder":"用戶名","class":"form-control"}) #自動生成input框 ) password = fields.CharField(required=True, error_messages={'required': '密碼不能爲空'}, widget=widgets.TextInput(attrs={'placeholder': '密碼', 'class': 'form-control'})) # 不能爲空 email = fields.EmailField( required=True, error_messages={"required":"郵箱不能爲空!!","invalid":"無效的郵箱"}, widget=widgets.EmailInput(attrs={"placeholder": "郵箱", "class": "form-control"}) # 自動生成input框 ) #不能爲空且郵箱格式要一致 def teacherindex(request): teacher_obj = models.UserInfo.objects.all() return render(request,"teacherindex.html",{"teacher_obj":teacher_obj}) def add(request): if request.method=="GET": form = TeacherForm() #只是讓顯示一個input框 return render(request,"add.html",{"form":form }) else: form = TeacherForm(data=request.POST) # print(form) #<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]> if form.is_valid(): # 開始驗證 # print('執行成功',form.cleaned_data) # 所有匹配成功,字典 form.cleaned_data['ut_id'] = 1 #要分的清是班主任還是講師 models.UserInfo.objects.all().create(**form.cleaned_data) return redirect("/teacherindex/") else: # print("=====?",form.errors,type(form.errors))#返回失敗的結果 # print(form.errors["username"][0]) #拿到返回失敗的結果,渲染到頁面 return render(request,"add.html",{"form":form})
前端html頁面:
{% block right %} <h1>添加老師信息</h1> <hr> <form method="post" novalidate> {% csrf_token %} <p>姓名:{{ form.username }}</p>{{ form.errors.username.0 }} <p>密碼:{{ form.password }}</p>{{ form.errors.password.0 }} <p>郵箱:{{ form.email }}</p>{{ form.errors.email.0 }} <p><input type="submit" value="提交"></p> </form> {% endblock %}