建立Form類時,主要涉及到 【字段】 和 【插件】,字段用於對用戶請求數據的驗證,插件用於自動生成HTMLcss
form組件的主要功能以下:html
1
2
3
4
5
6
7
8
9
10
|
from
django.db
import
models
class
UserInfo(models.Model):
nid
=
models.BigAutoField(primary_key
=
True
)
name
=
models.CharField(verbose_name
=
'用戶名'
, max_length
=
32
, unique
=
True
)
pwd
=
models.CharField(verbose_name
=
'密碼'
, max_length
=
64
)
email
=
models.EmailField(verbose_name
=
'郵箱'
, unique
=
True
)
tel
=
models.CharField(verbose_name
=
'手機'
)
avatar
=
models.ImageField(verbose_name
=
'頭像'
)
create_time
=
models.DateTimeField(verbose_name
=
'建立時間'
, auto_now_add
=
True
)
|
from django import forms from django.forms import widgets from app01.models import UserInfo from django.core.exceptions import ValidationError class RegisterForm(forms.Form): name = forms.CharField( required=True, min_length=6, max_length=32, label="用戶名", error_messages={ "required": "用戶名不能爲空", "min_length": "用戶名長度不能小於6個字符", "max_length": "用戶名長度不能大於32個字符"}, widget=widgets.TextInput(attrs={"class": "form-control"}) ) pwd = forms.CharField( required=True, min_length=6, max_length=32, label="密碼", error_messages={ "required": "密碼不能爲空", "min_length": "密碼長度不能小於6個字符", "max_length": "密碼長度不能大於32個字符"}, widget=widgets.PasswordInput(attrs={"class": "form-control"}) ) r_pwd = forms.CharField( required=True, min_length=6, max_length=32, label="確認密碼", error_messages={ "required": "密碼不能爲空", "min_length": "密碼長度不能小於6個字符", "max_length": "密碼長度不能大於32個字符"}, widget=widgets.TextInput(attrs={"class": "form-control"}) ) email = forms.EmailField( label="郵箱", error_messages={ "required": "郵箱不能爲空", "invalid": "格式錯誤,必須是郵箱格式" }, widget=widgets.TextInput(attrs={"class": "form-control"}) ) tel = forms.CharField( label="手機號", widget=widgets.TextInput(attrs={"class": "form-control"}) ) # 局部鉤子 def clean_name(self): val = self.cleaned_data.get("name") ret = UserInfo.objects.filter(name=val) if not ret: return val else: raise ValidationError("該用戶已註冊!") def clean_email(self): val = self.cleaned_data.get("email") ret = UserInfo.objects.filter(email=val) if not ret: return val else: raise ValidationError("該郵箱已註冊!") def clean_tel(self): val = self.cleaned_data.get("tel") if len(val) == 11: return val else: raise ValidationError("手機號格式錯誤") # 全局鉤子 def clean(self): pwd = self.cleaned_data.get('pwd') r_pwd = self.cleaned_data.get('r_pwd') if pwd and r_pwd: if pwd == r_pwd: return self.cleaned_data else: # raise ValidationError('兩次密碼不一致') # 加在全局的錯誤裏面 form.errors.get("__all__") self.add_error("r_pwd", ValidationError('兩次密碼不一致')) # 加在r_pwd的錯誤裏 else: return self.cleaned_data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
from
django.shortcuts
import
render,HttpResponse
from
app01.myforms
import
*
def
reg(request):
if
request.method
=
=
"POST"
:
form
=
RegisterForm(request.POST)
# form表單的name屬性值應該與forms組件字段名稱一致
if
form.is_valid():
# 驗證成功作什麼
form.cleaned_data.pop(
'r_pwd'
)
user_info
=
form.cleaned_data
UserInfo.objects.create(
*
*
user_info)
return
redirect(
'/'
)
else
:
return
render(request,
"reg.html"
,
locals
())
form
=
RegisterForm()
return
render(request,
"reg.html"
,
locals
())
'''
form=UserForm({"name":"bubu","email":"123@qq.com","xxxx":"123123123"}) :xxxx字段不會驗證,只驗證UserForm類裏面有的字段
form.is_valid() :返回布爾值
form.cleaned_data :全部乾淨的字段以及對應的值{"name":"bubu","email":"123@qq.com"}
form.errors :ErrorDict : {"校驗錯誤的字段":["錯誤信息",]}
form.errors.get("name") :ErrorList ["錯誤信息",]
form.errors.get("name")[0] :取出第一個錯誤信息
全局鉤子錯誤
forms中:
raise ValidationError('兩次密碼不一致') #加在全局的錯誤裏面 form.errors.get("__all__")
self.add_error("r_pwd", ValidationError('兩次密碼不一致'))
views.py中:errors=form.errors.get("__all__")
模板中:<span>{{ errors.0 }}</span>
'''
|
- 內部原理 def login(request): if request.method == 'GET': return render(request,'login.html') else: obj = LoginForm(request.POST) # is_valid """ 1. LoginForm實例化時, self.fields={ 'user': 正則表達式 'pwd': 正則表達式 } 2. 循環self.fields flag = True errors cleaned_data for k,v in self.fields.items(): # 1. user,正則表達式 input_value = request.POST.get(k) 正則表達式和input_value flag = False return flag """ if obj.is_valid(): print(obj.cleaned_data) else: print(obj.errors) return render(request,'login.html')
def ajax_login(request): if request.method == 'GET': return render(request, 'login.html') else: import json ret = {'status': True,'msg': None} obj = LoginForm(request.POST) if obj.is_valid(): print(obj.cleaned_data) else: # print(obj.errors) # obj.errors對象 ret['status'] = False ret['msg'] = obj.errors v = json.dumps(ret) return HttpResponse(v) <body> <h1>用戶登陸</h1> <form id="f1" > {% csrf_token %} <p> <input type="text" name="user" /> </p> <p> <input type="password" name="pwd" /> </p> <a onclick="submitForm();">提交</a> </form> <script src="/static/jquery-1.12.4.js"></script> <script> function submitForm(){ $('.c1').remove(); $.ajax({ url: '/ajax_login/', type: 'POST', data: $('#f1').serialize(),// user=alex&pwd=456&csrftoen=dfdf\ dataType:"JSON", success:function(arg){ console.log(arg); if(arg.status){ }else{ $.each(arg.msg,function(index,value){ console.log(index,value); var tag = document.createElement('span'); tag.innerHTML = value[0]; tag.className = 'c1'; $('#f1').find('input[name="'+ index +'"]').after(tag); }) } } }) } </script> </body>
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 ClassForm(Form): title = fields.RegexField('全棧\d+') # def class_list(request): cls_list = models.Classes.objects.all() return render(request,'class_list.html',{'cls_list':cls_list}) def add_class(request): if request.method == "GET": obj = ClassForm() return render(request,'add_class.html',{'obj': obj}) else: obj = ClassForm(request.POST) if obj.is_valid(): # obj.cleaned_data # 字典 # 數據庫建立一條數據 # print(obj.cleaned_data) # models.Classes.objects.create(title=obj.cleaned_data['tt']) models.Classes.objects.create(**obj.cleaned_data) return redirect('/class_list/') return render(request,'add_class.html',{'obj': obj}) def edit_class(request,nid): if request.method == "GET": row = models.Classes.objects.filter(id=nid).first() # 讓頁面顯示初始值 # obj = ClassForm(data={'title': 'asdfasdfasdfas'}) # 有HTML標籤,含有錯誤信息 obj = ClassForm(initial={'title': row.title}) # 只有HTML標籤 return render(request,'edit_class.html',{'nid': nid,'obj':obj}) else: obj = ClassForm(request.POST) if obj.is_valid(): models.Classes.objects.filter(id=nid).update(**obj.cleaned_data) return redirect('/class_list/') return render(request,'edit_class.html',{'nid': nid,'obj':obj}) class StudentForm(Form): name = fields.CharField( min_length=2, max_length=6, widget=widgets.TextInput(attrs={'class': 'form-control'}) ) email = fields.EmailField(widget=widgets.TextInput(attrs={'class': 'form-control'})) age = fields.IntegerField(min_value=18,max_value=25,widget=widgets.TextInput(attrs={'class': 'form-control'})) cls_id = fields.IntegerField( # widget=widgets.Select(choices=[(1,'上海'),(2,'北京')]) widget=widgets.Select(choices=models.Classes.objects.values_list('id','title'),attrs={'class': 'form-control'}) ) def student_list(request): stu_list = models.Student.objects.all() return render(request,'student_list.html',{'stu_list':stu_list}) def add_student(request): if request.method == "GET": obj = StudentForm() return render(request,'add_student.html',{'obj':obj}) else: obj = StudentForm(request.POST) if obj.is_valid(): models.Student.objects.create(**obj.cleaned_data) return redirect('/student_list/') return render(request,'add_student.html',{'obj':obj}) def edit_student(request,nid): if request.method == "GET": row = models.Student.objects.filter(id=nid).values('name','email','age','cls_id').first() obj = StudentForm(initial=row) return render(request,'edit_student.html',{'nid':nid,'obj': obj}) else: obj = StudentForm(request.POST) if obj.is_valid(): models.Student.objects.filter(id=nid).update(**obj.cleaned_data) return redirect('/student_list/') return render(request,'edit_student.html',{'nid':nid,'obj': obj}) def teacher_list(request): tea_list = models.Teacher.objects.all() return render(request,'teacher_list.html',{'tea_list':tea_list}) from django.forms import models as form_model class TeacherForm(Form): tname = fields.CharField(min_length=2) # xx = form_model.ModelMultipleChoiceField(queryset=models.Classes.objects.all()) # xx = form_model.ModelChoiceField(queryset=models.Classes.objects.all()) xx = fields.MultipleChoiceField( # choices=models.Classes.objects.values_list('id','title'), widget=widgets.SelectMultiple ) def __init__(self,*args,**kwargs): super(TeacherForm,self).__init__(*args,**kwargs) self.fields['xx'].choices = models.Classes.objects.values_list('id','title') # obj = TeacherForm() # 1. 找到全部字段 # 2. self.fields = { # tname: fields.CharField(min_length=2) # } def add_teacher(request): if request.method == "GET": obj = TeacherForm() return render(request,'add_teacher.html',{'obj':obj}) else: obj = TeacherForm(request.POST) if obj.is_valid(): xx = obj.cleaned_data.pop('xx') row = models.Teacher.objects.create(**obj.cleaned_data) row.c2t.add(*xx) # [1,2] return redirect('/teacher_list/') return render(request,'add_teacher.html',{'obj':obj}) def edit_teacher(request,nid): if request.method == "GET": row = models.Teacher.objects.filter(id=nid).first() class_ids = row.c2t.values_list('id') # print(class_ids) # id_list = [] id_list = list(zip(*class_ids))[0] if list(zip(*class_ids)) else [] # obj = TeacherForm(initial={'tname':row.tname,'xx':[1,2,3]}) obj = TeacherForm(initial={'tname':row.tname,'xx':id_list}) return render(request,'edit_teacher.html',{'obj':obj}) # # class TestForm(Form): # t1 = fields.CharField( # widget=widgets.Textarea(attrs={}) # ) # # # t2 = fields.CharField( # widget=widgets.CheckboxInput # ) # # t3 = fields.MultipleChoiceField( # choices=[(1,'籃球'),(2,'足球'),(3,'溜溜球')], # widget=widgets.CheckboxSelectMultiple # ) # # t4 = fields.ChoiceField( # choices=[(1,'籃球'),(2,'足球'),(3,'溜溜球')], # widget=widgets.RadioSelect # ) # t5 = fields.FileField( # widget=widgets.FileInput # ) # def clean_t1(self): # pass from django.core.exceptions import ValidationError class TestForm(Form): user = fields.CharField(validators=[]) pwd = fields.CharField() def clean_user(self): v = self.cleaned_data['user'] if models.Student.objects.filter(name=v).count(): raise ValidationError('用戶名已經存在') return self.cleaned_data['user'] def clean_pwd(self): return self.cleaned_data['pwd'] def clean(self): # user = self.cleaned_data.get('user') # email = self.cleaned_data.get('email') # if models.Student.objects.filter(user=user,email=email).count(): # raise ValidationError('用戶名和郵箱聯合已經存在') return self.cleaned_data # def _post_clean(self): # """ # An internal hook for performing additional cleaning after form cleaning # is complete. Used for model validation in model forms. # """ # pass def test(request): obj = TestForm(initial={'t3':[2,3]}) obj.is_valid() return render(request,'test.html',{'obj':obj})
<body> <h1>班級列表</h1> <div> <a href="/add_class/">添加</a> </div> <ul> {% for row in cls_list %} <li>{{ row.title }} <a href="/edit_class/{{ row.id }}/">編輯</a> </li> {% endfor %} </ul> </body> <body> <h1>添加班級</h1> <form method="POST" action="/add_class/" novalidate> {% csrf_token %} {{ obj.title }} {{ obj.errors.title.0 }} <input type="submit" value="提交" /> </form> </body> <body> <h1>編輯班級</h1> <form method="POST" action="/edit_class/{{ nid }}/"> {% csrf_token %} <p> {{ obj.title }} {{ obj.errors.title.0 }} </p> <input type='submit' value="提交" /> </form> </body> <body> <h1>添加學生</h1> <form action="/add_student/" method="POST"> {% csrf_token %} <p> {{ obj.name }} </p> <p> {{ obj.email }} </p> <p> {{ obj.age }} </p> <p> {{ obj.cls_id }} <!--/////////////////////////--> </p> <input type="submit" value="提交" /> </form> </body> <body> <h1>學生列表</h1> <a href="/add_student/">添加</a> <ul> {% for row in stu_list %} <li>{{ row.name }}-{{ row.email }}-{{ row.age }}-{{ row.cls_id }}-{{ row.cls.title }} <a href="/edit_student/{{ row.id }}/">編輯</a></li> {% endfor %} </ul> </body>
from django.forms import Form from django.forms import fields from django.forms import widgets from django.core.exceptions import ValidationError class RegisterForm(Form): username = fields.CharField( widget=widgets.TextInput(attrs={'class':'form-control'}) ) password = fields.CharField( widget=widgets.PasswordInput(attrs={'class':'form-control'}) ) password2 = fields.CharField( widget=widgets.PasswordInput(attrs={'class':'form-control'}) ) avatar = fields.FileField(widget=widgets.FileInput(attrs={'id':"imgSelect",'class':"f1" })) code = fields.CharField( widget=widgets.TextInput(attrs={'class':'form-control'}) ) def __init__(self,request,*args,**kwargs): super(RegisterForm,self).__init__(*args,**kwargs) self.request = request def clean_code(self): input_code = self.cleaned_data['code'] session_code = self.request.session.get('code') if input_code.upper() == session_code.upper(): return input_code raise ValidationError('驗證碼錯誤') # def clean_password2(self): # p1 = self.cleaned_data['password'] # p2 = self.cleaned_data['password2'] # return p2 def clean(self): p1 = self.cleaned_data.get('password') p2 = self.cleaned_data.get('password2') if p1 == p2: # return self.cleaned_data return None # self.add_error(None,ValidationError('密碼不一致')) self.add_error("password2",ValidationError('密碼不一致')) ################################################################### from app01.forms import RegisterForm from django.core.exceptions import NON_FIELD_ERRORS def register(request): """ 用戶註冊 :param request: :return: """ if request.method == "GET": obj = RegisterForm(request) return render(request,'register.html',{'obj':obj}) else: # 驗證碼操做 obj = RegisterForm(request,request.POST,request.FILES) if obj.is_valid(): pass else: print(obj.errors['__all__']) print(obj.errors[NON_FIELD_ERRORS]) # obj.errors """ { __all__: [錯誤1,錯誤2] user: [錯誤1,錯誤2] password: [錯誤1,錯誤2] } """ return render(request,'register.html',{'obj':obj}) ################################################################### # 方式一:views.py中:form.errors['__all__'] 或者 form.errors[NON_FIELD_ERRORS] 模板中:{{ form.non_field_errors }} 獲取 __all__的錯誤 # 方式二:views.py中:errors=form.errors.get("__all__") 模板中:<span>{{ errors.0 }}</span>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
<!
DOCTYPE
html>
<
html
lang="en">
<
head
>
<
meta
charset="UTF-8">
<
title
>Title</
title
>
<
style
>
.error{
color: red;
}
.register {
width: 400px;
margin-top: 20px;
margin-left: auto;
margin-right: auto;
border: 1px solid #f0f0f0;
padding: 10px 30px 50px 30px;
-webkit-box-shadow: 5px 10px 10px rgba(0, 0, 0, .05);
box-shadow: 5px 10px 10px rgba(0, 0, 0, .05);
}
.register h3{font-size: 25px; text-align: center;font-weight: bold;}
</
style
>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<
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
class="register">
<
h3
>用戶註冊</
h3
>
<
form
action="" method="post" novalidate>
{% csrf_token %}
<
div
class="form-group">
<
label
for="id_name">{{ form.name.label }}</
label
>
{{ form.name }} <
span
class="pull-right error">{{ form.name.errors.0 }}</
span
>
</
div
>
<
div
class="form-group">
<
label
for="id_pwd">{{ form.pwd.label }}</
label
>
{{ form.pwd }} <
span
class="pull-right error">{{ form.pwd.errors.0 }}</
span
>
</
div
>
<
div
class="form-group">
<
label
for="id_r_pwd">確認密碼</
label
>
{{ form.r_pwd }} <
span
class="pull-right error">{{ form.r_pwd.errors.0 }}</
span
><
span
class="pull-right error">{{ errors.0 }}</
span
>
</
div
>
<
div
class="form-group">
<
label
for="id_email">郵箱</
label
>
{{ form.email }} <
span
class="pull-right error">{{ form.email.errors.0 }}</
span
></
div
>
<
div
class="form-group">
<
label
for="id_tel">手機號</
label
>
{{ form.tel }} <
span
class="pull-right error">{{ form.tel.errors.0 }}</
span
></
div
>
<
input
type="submit" class="btn btn-default" value="註冊"/>
</
form
>
<!--
<h3>forms組件渲染方式2</h3>
<form action="" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label for="{{ field.auto_id }}">{{ field.label }}</label>
{{ field }} <span class="pull-right error">{{ field.errors.0 }}</span>
</div>
{% endfor %}
<input type="submit" class="btn btn-default" value="註冊"/>
</form>
<h3>forms組件渲染方式3</h3>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-default" value="註冊"/>
</form>
-->
</
div
>
</
body
>
</
html
>
|
from django import forms from django.forms import widgets from blog.models import UserInfo from django.core.exceptions import ValidationError from django.core.validators import RegexValidator class TestForm(forms.Form): user = forms.CharField( min_length=8, label="用戶名", initial="張三", # 初始值,input框裏面的初始值。 error_messages={ # 重寫錯誤信息。 "required": "不能爲空", "invalid": "格式錯誤", "min_length": "用戶名最短8位" } ) pwd = forms.CharField( min_length=6, label="密碼", widget=widgets.PasswordInput(attrs={'class': 'form-control'}) ) content = forms.CharField( widget=widgets.TextInput(attrs={'id': 'i1', 'class': 'form-control'}) ) # 單radio,值爲字符串 gender = forms.ChoiceField( # choices=((1, '男'), (2, '女'),), initial=2, widget=widgets.RadioSelect() ) # 單checkbox keep = forms.fields.ChoiceField( label="是否記住密碼", initial="checked", widget=forms.widgets.CheckboxInput() ) # 多選checkbox,值爲列表 hobbies1 = forms.MultipleChoiceField( initial=[2, ], choices=((1, '足球'), (2, '籃球'),), widget=widgets.CheckboxSelectMultiple() ) # 單select,值爲字符串 city = forms.ChoiceField( choices=((1, '上海'), (2, '北京'),), initial=2, widget=widgets.Select() ) # 多選select,值爲列表 hobbies2 = forms.MultipleChoiceField( choices=((1, '足球'), (2, '籃球'),), initial=[1, ], widget=widgets.SelectMultiple() ) """ #choice字段注意事項 在使用選擇標籤時,須要注意choices的選項能夠從數據庫中獲取,可是因爲是靜態字段 ***獲取的值沒法實時更新***, 方法1:那麼須要自定義構造方法從而達到此目的。 """ def __init__(self, *args, **kwargs): super(TestForm, self).__init__(*args, **kwargs) # self.fields['city2'].choices = ((1, '上海'), (2, '北京'),) # 或 self.fields['gender'].choices = ((1, '男'), (2, '女'),) self.fields['city'].choices = UserInfo.objects.all().value_list('id', 'caption') self.fields['hobbies1'].choices = UserInfo.objects.all().value_list('id', 'hobbies') self.fields['hobbies2'].choices = UserInfo.objects.all().value_list('id', 'hobbies') """ 在使用選擇標籤時,須要注意choices的選項能夠從數據庫中獲取,可是因爲是靜態字段 ***獲取的值沒法實時更新***, 方法2:使用django提供的ModelChoiceField和ModelMultipleChoiceField字段來實現 """ class TestForm2(forms.Form): authors = forms.ModelMultipleChoiceField(queryset=UserInfo.objects.all()) # authors = forms.ModelChoiceField(queryset=UserInfo.objects.all()) # authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) # 多選 # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all()) # 單選
1、表單的綁定屬性 Form.is_bound:若是你須要區分綁定的表單和未綁定的表單,能夠檢查下表單的is_bound屬性值 f = ContactForm({}) f.is_bound 空字典也是True 2、使用表單驗證數據 Form.clean()若是你要自定義驗證功能,那麼你須要從新實現這個clean方法。 Form.is_valid()調用is_valid()方法來執行綁定表單的數據驗證工做,並返回一個表示數據是否合法的布爾值。 Form.errors 表單的errors屬性保存了錯誤信息字典 Form.errors.as_data() 返回一個字典,它將字段映射到原始的ValidationError實例。 Form.errors.as_json(escape_html=False) 返回JSON序列化後的錯誤信息字典。 Form.add_error(field, error) 向表單特定字段添加錯誤信息。 field參數爲字段的名稱。若是值爲None,error將做爲Form.non_field_errors()的一個非字段錯誤。 Form.has_error(field, code=None) 判斷某個字段是否具備指定code的錯誤。當code爲None時,若是字段有任何錯誤它都將返回True。 Form.non_field_errors() 返回Form.errors中不是與特定字段相關聯的錯誤。 對於沒有綁定數據的表單 驗證沒有綁定數據的表單是沒有意義的。即 f = ContactForm({}) f.is_valid() 是False 3、檢查表單數據是否被修改 Form.has_changed() 當你須要檢查表單的數據是否從初始數據發生改變時,能夠使用has_changed()方法。 Form.changed_data返回有變化的字段的列表。 4、訪問表單中的字段 Form.cleaned_data:若是你的數據沒有經過驗證,cleaned_data字典中只包含合法的字段 經過fileds屬性訪問表單的字段: f.fields['name'].label = "Username" 5、表單的HTML生成方式 Form.as_p() Form.as_ul() Form.as_table()
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, 自定製正則表達式 phone = fields.RegexField('139\d+') 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類型 ...
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:RegexValidator驗證器 """ from django import forms from django.forms import widgets from django.core.exceptions import ValidationError from django.core.validators import RegexValidator from blog.models import UserInfo class FInfo(forms.Form): user = forms.CharField(max_length=5, validators=[RegexValidator(r'^[0-9]+$', '請輸入數字', 'invalid'), RegexValidator(r'^159[0-9]+$', '數字必須以159開頭')], ) def clean_user(self): val = self.cleaned_data.get("username") user = UserInfo.objects.filter(username=val).first() if not user: return val else: raise ValidationError("該用戶已註冊!") """ 方式2:自定義驗證函數 """ import re from django import forms from django.forms import widgets from django.core.exceptions import ValidationError # 自定義驗證規則 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('手機號碼格式錯誤') class PublishForm(forms.Form): title = forms.CharField(max_length=20, min_length=5, error_messages={'required': '標題不能爲空', 'min_length': '標題最少爲5個字符', 'max_length': '標題最多爲20個字符'}, widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': '標題5-20個字符'})) # 使用自定義驗證規則--自定義方法 phone = forms.CharField(validators=[mobile_validate, ], error_messages={'required': '手機不能爲空'}, widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': '手機號碼'})) email = forms.EmailField(required=False, error_messages={'required': '郵箱不能爲空', 'invalid': '郵箱格式錯誤'}, widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': '郵箱'}))
from django import forms from django.core.exceptions import ValidationError class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用戶名", initial="張三", error_messages={ "required": "不能爲空", "invalid": "格式錯誤", "min_length": "用戶名最短8位" }, widget=forms.widgets.TextInput(attrs={"class": "form-control"}) ) password = forms.CharField( min_length=6, label="密碼", widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'}, render_value=True) ) re_password = forms.CharField( min_length=6, label="確認密碼", widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'}, render_value=True) ) # 定義局部鉤子,用來校驗username字段 def clean_username(self): value = self.cleaned_data.get("username") if "666" in value: raise ValidationError("光喊666是不行的") else: return value # 定義全局的鉤子,用來校驗密碼和確認密碼字段是否相同 def clean(self): password_value = self.cleaned_data.get('password') re_password_value = self.cleaned_data.get('re_password') if password_value == re_password_value: return self.cleaned_data else: self.add_error('re_password', '兩次密碼不一致') raise ValidationError('兩次密碼不一致') # 批量添加樣式 def __init__(self, *args, **kwargs): super(LoginForm, self).__init__(*args, **kwargs) for field in iter(self.fields): self.fields[field].widget.attrs.update({ 'class': 'form-control' })
屬性 | 說明 |
---|---|
{{ field.label }} |
字段對應的label信息 |
{{ field.label_tag }} |
自動生成字段的label標籤,注意與{{ field.label }} 的區別。 |
{{ field.id_for_label }} |
自定義字段標籤的id |
{{ field.value }} |
當前字段的值,好比一個Email字段的值someone@example.com |
{{ field.html_name }} |
指定字段生成的input標籤中name屬性的值 |
{{ field.help_text }} |
字段的幫助信息 |
{{ field.errors }} |
包含錯誤信息的元素 |
{{ field.is_hidden }} |
用於判斷當前字段是否爲隱藏的字段,若是是,返回True |
{{ field.field }} |
返回字段的參數列表。例如{{ char_field.field.max_length }} |
Django提供了兩種獨立的方法,用於循環那些不可見的和可見的字段,hidden_fields()和visible_fields()python
屬性 |
---|
{% for field in form.visible_fields %}....{% endfor %} |
{% for field in form.hidden_fields %}....{% endfor %} |