为什么要用forms组件 一般前端js代码可以对数据进行普通校验,但是js可以被绕过,例如爬虫,所以后端必须做校验,保证数据安全。前端做校验可减轻后端压力。 forms特点 自动生成表单html代码 校验数据 返回校验信息及html代码 使用forms组件
from django import forms
class RegForm(forms.Form):
name = forms.CharField(max_length=10, label='姓名', required=False, error_messages={
'required': '可以为空',
})
froms字段参数
参数名 | 解释 | 参数类型 | 注释 |
max_length | 最大长度 | int | |
label | 输入框名字 | str | |
required | 校验允许为空 | bool | True表示不能为空 |
error_messages | 错误提示信息 | dict | key和限制字段参数一一对应 |
widget | 输入框类型 | forms.widgets.* | |
choices | 选择的数据 | tuple | 例如((0, '男'), (1, '女'), (2, '保密')),只有ChoiceField才有 |
initial | 默认值 | int或list或str | 单选为int或'checked',多选为list |
validators | 正则校验列表 | list | 例如[RegexValidator(r'^[0-9]*$', '必须是数字'),] from django.core.validators import RegexValidator |
widgets参数
参数名 | 解释 | 参数类型 | 注释 |
render_value | 是否返回值 | bool | True会将出错数据和错误信息都返回,False只返回错误信息 |
attrs | html标签属性 | dict | 设置如class等属性 |
创建forms对象 regForm= RegForm(request.POST) # regForm.data 将要进行校验的数据 dict # regForm.cleaned_data 成功校验的数据 dict # 校验 True校验成功 只有执行了这个方法才会执行校验 regForm.is_valid() 自定义校验(使用框架的hook) 在forms定义方法'clean_%s' % name 方法例如 name是具体的字段名
def clean_name(self):
from django.core.exceptions import ValidationError
if self.cleaned_data['name'] == '':
raise ValidationError('name 不能为空')
return self.cleaned_data['name']
重写父类clean方法,例如
def clean(self):
if "自定义校验" != '':
raise ValidationError('error')
return self.cleaned_data
具体单选、复选、下拉框看例子:
from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
class RegForm(forms.Form):
# 输入框
name = forms.CharField(max_length=10,
label='姓名',
required=False,
error_messages={
'required': '可以为空',
})
# 密码框
pwd = forms.CharField(
max_length=16,
min_length=6,
label='密码',
widget=forms.widgets.PasswordInput(render_value=False),
error_messages={
'min_length': '密码至少6位',
'max_length': '密码最多16位',
})
# 邮箱框
email = forms.EmailField()
# radio单选框
gender = forms.ChoiceField(
choices=((0, '男'), (1, '女'), (2, '保密')),
widget=forms.widgets.RadioSelect(),
initial=2,
)
# select单选下拉框
hobby = forms.ChoiceField(
choices=((0, '足球'), (1, '排球'), (2, '肉球')),
widget=forms.widgets.Select(),
initial=2,
)
# select多选框
hobbys = forms.MultipleChoiceField(
choices=((0, '足球'), (1, '排球'), (2, '肉球')),
widget=forms.widgets.SelectMultiple(),
initial=[1, 2]
)
# checkbox单选框
# status = forms.ChoiceField(
# widget=forms.widgets.CheckboxInput,
# initial='checked',
# )
# checkbox多选框
choice = forms.MultipleChoiceField(
choices=((0, '足球'), (1, '篮球'), (2, '乒乓球')),
widget=forms.widgets.CheckboxSelectMultiple(),
initial=[1, 2]
)
# 日期选择框
# birthday = forms.DateTimeField(
# widget=forms.widgets.SelectDateWidget(),
# )
# 正则校验
phone = forms.CharField(
validators=[RegexValidator(r'^[0-9]*$', '必须是数字'), RegexValidator(r'^1[3-9][0-9]{9}$', '格式不正确')]
)
# 从数据库取值作为参数 需自在定义__init__()方法内查询数据库内容
city = forms.ChoiceField(
choices=(),
widget=forms.widgets.Select(),
initial=2,
)
def clean_name(self):
if self.cleaned_data['name'] == '':
raise ValidationError('name 不能为空')
return self.cleaned_data['name']
def clean(self):
if "自定义校验" != '':
raise ValidationError('error')
return self.cleaned_data
def __init__(self, *args, **kwargs):
super(RegForm, self).__init__(*args, **kwargs)
self.fields['city'].widgets.choices = models.City.objects.all().values_list('id', 'name')
html页面两种展示示例
批量被p标签包住
<form action="/reg" method="post">
{% csrf_token %}
{{ regForm.as_p }}
{{ regForm.errors }}
<input type="submit" value="submit">
</form>
单个标签(推荐使用)
<form action="/reg" method="post">
{% csrf_token %}
<div>
{{ regForm.name.label }}
{{ regForm.name }}
<span>{{ regForm.name.errors.0 }}</span>
</div>
<div>
{{ regForm.pwd.label }}
{{ regForm.pwd }}
<span>{{ regForm.pwd.errors.0 }}</span>
</div>
<input type="submit" value="submit">
</form>
总结:后端必须做校验,校验方式要根据具体校验数据确定