Form介绍
我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。
与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确。如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.。
Django form组件就实现了上面所述的功能。
总结一下,其实form组件的主要功能如下:
1.生成页面可用的HTML标签
- form_obj.as_p
- 自己挨个字段取
{{ from_obj.name.label}}
{{ form_obj.name}}
- for循环 迭代
{% for field in form_obj %}
{{ field.label}}
{{ field }}
{% endfor %}
2.对用户提交的数据进行校验
3.保留上次输入内容(render_value=True)
eg.
widget=forms.widgets.PasswordInput(attrs={"class":"form-control"}, render_value=True)
使用form组件实验注册功能示例
1.先定义一个RegForm类
from django import forms
class RegForm(forms.Form):
name = forms.CharField(max_length=16,
label="用户名",
error_messages={
"max_length": "用户名最多为16位",
"required": "该字段不能为空",
},
widget=forms.TextInput(attrs={"class": "form-control"})
)
2.写一个视图函数
def reg(request):
form_obj = RegForm()
if request.method == "POST":
form_obj = RegForm(request.POST)
if form_obj.is_valid():
# 校验通过
# 把数据存到数据库
del form_obj.cleaned_data["re_pwd"]
models.UesrInfo.objects.create(**form_obj.cleaned_data)
return HttpResponse("注册成功!")
return render(request, "reg2.html", {"form_obj": form_obj})
3.写HTML页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>form组件</title>
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form action="/reg2/" method="post" novalidate>
{% csrf_token %}
<div class="form-group {% if form_obj.name.errors.0 %}has-error{% endif %}">
{{ form_obj.name.label }}
{{ form_obj.name }}
<span class="help-block">{{ form_obj.name.errors.0 }}</span>
</div>
<div class="form-group {% if form_obj.pwd.errors.0 %}has-error{% endif %}">
{{ form_obj.pwd.label }}
{{ form_obj.pwd }}
<span class="help-block">{{ form_obj.pwd.errors.0 }}</span>
</div>
<div class="form-group {% if form_obj.re_pwd.errors.0 %}has-error{% endif %}">
{{ form_obj.re_pwd.label }}
{{ form_obj.re_pwd }}
<span class="help-block">{{ form_obj.re_pwd.errors.0 }}</span>
</div>
<div class="form-group {% if form_obj.email.errors.0 %}has-error{% endif %}">
{{ form_obj.email.label }}
{{ form_obj.email }}
<span class="help-block">{{ form_obj.email.errors.0 }}</span>
</div>
<div class="form-group {% if form_obj.mobile.errors.0 %}has-error{% endif %}">
{{ form_obj.mobile.label }}
{{ form_obj.mobile }}
<span class="help-block">{{ form_obj.mobile.errors.0 }}</span>
</div>
<div class="form-group {% if form_obj.city.errors.0 %}has-error{% endif %}">
{{ form_obj.city.label }}
{{ form_obj.city }}
<span class="help-block">{{ form_obj.city.errors.0 }}</span>
</div>
<div>
<input type="submit" class="btn btn-default">
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Form常用字段
initial
初始值,input框里面的初始值。
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三" # 设置默认值
)
error_messages
重写错误信息。
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三",
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短8位"
}
)
password
pwd = forms.CharField(
min_length=6,
label="密码",
widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
radioSelect
单选Select
多选Select
单选checkbox
多选checkbox
choice字段注意事项
在使用选择标签时,需要注意choices的选项可以配置从数据库中获取,但是由于是静态字段 获取的值无法实时更新,需要重写构造方法从而实现choice实时更新。
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')
字段校验
RegexValidator验证器
验证手机号
mobile = forms.CharField(
label="手机号",
max_length=11,
# 自定义校验规则
validators=[
RegexValidator(r'^[0-9]+$', '手机号必须是数字'),
RegexValidator(r'^1[3-9][0-9]{9}$', '手机号格式有误'),
],
widget=widgets.TextInput(attrs={"class": "form-control"}),
error_messages={
"max_length": "手机号最多为11位",
"required": "该字段不能为空",
},
)
自定义验证函数
Hook方法
局部钩子
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"})
)
...
# 定义局部钩子,用来校验username字段
def clean_username(self):
value = self.cleaned_data.get("username")
if "666" in value:
raise ValidationError("光喊666是不行的")
else:
return value