form Form component
When submitting data to the back end before we use a form in an HTML page form, will write the label to obtain user input and label them with a form wrap.
At the same time we all need to do in a lot of scenes of user input validation, such as checking whether the user input, the input length and format is not correct. If the user input has an error requires appropriate error message corresponding to the location on the page ..
Django form component to achieve the functions described above.
To sum up, in fact, the main function of form components as follows:
- HTML tags generated pages available
- To verify the data submitted by users
- Keep last Input content
First, write your own check
Filter keywords such as:
- Registration function,
- Registered user name can not contain sensitive words such as jinpingmei, if given input error
- The password entered by the user can not be less than three, less than three mask prompts the user if the password is too short
- Note: check data parity typically have front and rear ends, the front end of the check optional but even then regressed, must also have the rear end of the front end of the check word may anyway have no checksum must verify rear! ! !
<body>
<form action="" method="post">
{{ back_dic }}
<p>username:
<input type="text" name="username">
<span style="color:red">{{ back_dic.username }}</span>
</p>
<p>password:<input type="text" name="password">
<span style="color:red">{{ back_dic.password }}</span>
</p>
<input type="submit">
</form>
</body>
# urls.py
from app01 import views
urlpatterns = [
url(r'^register/', views.register),
]
# views.py
def register(request):
back_dic = {'username': '', 'password': ''}
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if 'jinpingmei' in username:
back_dic['username'] = "敏感词汇"
if len(password) < 3:
back_dic['password'] = '长度不能小于三'
return render(request, '03register.html', locals())
to sum up:
- Set up the front page to make their own
- To do their own test data
- Display error messages do it yourself
Second, the use of the form component
Importingfrom django import forms
Define a class MyRegForm 2.1
class MyRegForm(forms.Form):
username = forms.CharField(min_length=3, max_length=5)
password = forms.CharField(min_length=3, max_length=6)
email = forms.EmailField()
2.2 check data
#校验数据导入模块
from app01 import views
# 1. 给自定义的类传一个字典
obj = views.MyRegForm({'username':'randy',"password":"123", 'email:':'12345'})
# 2.判断数据是否全部合法
obj.is_valid()
Out[8]: False
# 3.查看符合数据的字段
obj.cleaned_data
Out[9]: {'username': 'randy', 'password': '123'}
# 4.查看不符合条件的数据,以及显示符合数据的原因
obj.errors
Out[10]: {'email': ['This field is required.']}
# 5.校验数据的时候 默认情况下类里面所有的字段都必须传值
obj = views.MyRegForm({'username':'randy',"password":"12"})
obj.is_valid()
Out[12]: False
obj.errors
Out[13]:
{'password': ['Ensure this value has at least 3 characters (it has 2).'],
'email': ['This field is required.']}
# 6.默认情况下可以多传 但是绝对不能少传
obj = views.MyRegForm({'username':'randy','password':'123','email':'[email protected]','res':'ooo'})
obj.is_valid()
Out[15]: True
2.3 page rendering in three ways
forms components will help you render obtain user input (input, select, drop-down box ...) tags need to manually write the submit button
# urls.py
from app01 import views
urlpatterns = [
url(r'^formss/', views.formss),
]
# views.py
def formss(request):
# 1. 生成一个空对象
form_obj = MyRegForm() # 两个对象名要相同
if request.method == 'POST':
#2. 获取用户提交的数据
print(request.POST)
# 3.记住与form组件帮助我们校验
form_obj = MyRegForm(request.POST)
# 4 判断用户输入的数据是否符合校验规则
if form_obj.is_valid():
return HttpResponse("上传的数据没有问题")
else:
return HttpResponse("上传的数据存在问题")
return render(request, '04formss表单校验.html', locals())
Rendering a page
<form action="" method="post" novalidate>
<h2>页面渲染方式一</h2>
{{ form_obj.as_p }} <!--as_p指定包裹的标签,采用p标签包裹-->
{#{{ form_obj.as_ul }}#}
<input type="submit" value="验证">
</form>
The first front page rendering by: too high a level package style tag and convenient adjustment parameter poor scalability (not recommended)
<form action="" method="post" novalidate>
<h2>页面渲染方式二</h2>
<p>
{{ form_obj.username.label }}{{ form_obj.username }}
</p>
<p>
{{ form_obj.password.label }}{{ form_obj.password }}
</p>
<p>
{{ form_obj.email.label }} {{ form_obj.email }}
</p>
<input type="submit" value="验证">
</form>
The second way to render the page: inadequate at higher scalability that you need more than hand-written code (not recommended)
<form action="" method="post" novalidate>
<h2>页面渲染方式三</h2>
{% for res in form_obj %}
<p>
{{ res.label }}:{{ res }}
<span style="color:red">{{ res.errors.0 }}</span>
</p>
{% endfor %}
<input type="submit" value="验证">
</form>
The third rendering of the front page of the way: the amount of code and scalability are high (recommended), display an error message with an object point errors.0
Three, form other authentication parameters
from django import forms
from django.forms import widgets # 当你forms点不出来的时候 你可以手动导入一下
from django.core.validators import RegexValidator
class MyRegForm(forms.Form):
username = forms.CharField(min_length=3, max_length=5,
error_messages={
'min_length': '用户最短三位',
'max_length': '用户最长八位',
'required': '用户名不能为空',
}, initial='设置初始值', required=False,
widget=forms.widgets.TextInput(attrs={'class': 'form-control other'}))
password = forms.CharField(min_length=3, max_length=6,
error_messages={
'min_length': '密码最短三位',
'max_length': '密码最长八位',
'required': '密码不能为空'
})
confirm_password = forms.CharField(min_length=3, max_length=8, label='确认密码',
error_messages={
'min_length': '确认密码最短三位',
'max_length': '确认密码最长八位',
'required': '确认密码不能为空'
})
email = forms.EmailField(label='邮箱',
error_messages={
'required': '邮箱不能为空',
'invalid': '邮箱格式不正确'
}, required=False)
phone = forms.CharField(label='手机号',validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')])
Parameter Description:
- min_length: The minimum length of the data
- max_length: The maximum length of data
- error_messages: corresponding to given information,
- required: can not be empty
- widget: add style to the label, can be achieved by adding more spaces
- validators: supports regular expressions
Fourth, the hook function
forms provided by the label check, but also can not satisfy you, you can use the hook function to add additional verification
4.1 partial hook function
class MyRegForm(forms.Form):
username = forms.CharField(min_length=3, max_length=10)
password = forms.CharField(min_length=3, max_length=6)
confirm_password = forms.CharField(min_length=3, max_length=8, label='确认密码')
email = forms.EmailField(label='邮箱')
# 当需要对某一个字段数据进行额外的数据校验,可以使用钩子函数
# 针对单个字段,使用局部钩子
def clean_username(self):
# 获取标签
username = self.cleaned_data.get("username")
if 'jinpingmei' in username:
# 给username字段下面提示错误信息
# raise ValidationError("输入敏感词汇)
self.add_error('username', '输入敏感词汇')
return username
4.2 global hook function
class MyRegForm(forms.Form):
username = forms.CharField(min_length=3, max_length=10)
password = forms.CharField(min_length=3, max_length=6)
confirm_password = forms.CharField(min_length=3, max_length=8, label='确认密码')
email = forms.EmailField(label='邮箱')
# 针对多个字段的校验使用全局钩子
def clean(self):
username = self.cleaned_data.get('username')
confirm_password = self.cleaned_data.get("confirm_password")
if not confirm_password == username:
self.add_error("confirm_password", "两次密码输入不一样")
return self.cleaned_data
Five other fields constraints
Common Fields with plug-ins
When creating Form class, mainly related to the field of [] and [] plug, field is used to authenticate the user requesting the data, for automatically generating the HTML plug;
initial
The initial value, the initial value input box inside.
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三" # 设置默认值
)
pwd = forms.CharField(min_length=6, label="密码")
error_messages
Rewrite error message.
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三",
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短8位"
}
)
pwd = forms.CharField(min_length=6, label="密码")
password
class LoginForm(forms.Form):
...
pwd = forms.CharField(
min_length=6,
label="密码",
widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
)
radioSelect
Value is a string of single radio
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三",
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短8位"
}
)
pwd = forms.CharField(min_length=6, label="密码")
gender = forms.fields.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性别",
initial=3,
widget=forms.widgets.RadioSelect()
)
Radio Select
class LoginForm(forms.Form):
...
hobby = forms.ChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
label="爱好",
initial=3,
widget=forms.widgets.Select()
)
Select multiple choice
class LoginForm(forms.Form):
...
hobby = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
label="爱好",
initial=[1, 3],
widget=forms.widgets.SelectMultiple()
)
Radio checkbox
class LoginForm(forms.Form):
...
keep = forms.ChoiceField(
label="是否记住密码",
initial="checked",
widget=forms.widgets.CheckboxInput()
)
Multi-select checkbox
class LoginForm(forms.Form):
...
hobby = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.CheckboxSelectMultiple()
)
choice field considerations
When using the select tag, you need to pay attention to choices of configuration options can be obtained from the database, but because it is the value of static fields taken not immediately update, you need to override the constructors choice in order to achieve real-time updates.
method one:
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')
Second way:
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()) # 单选
Django Form All built-in fields
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类型
Field validation
RegexValidator validator
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator
class MyForm(Form):
user = fields.CharField(
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
)
Custom validation function
import re
from django.forms import Form
from django.forms import widgets
from django.forms import fields
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(Form):
title = fields.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 = fields.CharField(validators=[mobile_validate, ],
error_messages={'required': '手机不能为空'},
widget=widgets.TextInput(attrs={'class': "form-control",
'placeholder': u'手机号码'}))
email = fields.EmailField(required=False,
error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'},
widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'}))