建立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 %} |