文章目录
- 生成 html 代码
- 校验规则
- 参数校验
- 正则校验
- 自定义校验
- Hook 校验
生成 html 代码
- views.py
# 中需要导入模块
from django import forms, views
# 然后新建一个类, 这个类要继承 forms.Form
class BookForm(forms.Form):
# 按照 models.py 中依次创建, 类似 models.CharField 改为 forms.CharField
title = forms.CharField(
max_length=16,
# label 是 label 标签的内容, 不填展示为 "title"
label="书名",
# widget 为插件
widget=forms.TextInput(
# 可以为标签添加属性
attrs={
"class": "form-control",
"placeholder": "此处填写书名",
}
)
)
class BookAdd(views.View):
def get(self):
# 实例化
form_obj = BookForm()
# 此处 locals 表示环境内所有变量
return render(request, "book_add.html", locals())
- book_add.html
<!-- novalidate 表示不检查, autocomplate="off"表示不补全 -->
<form action="" method="post" novalidate autocomplete="off">
{% csrf_token %}
<div class="col-md-8 col-md-offset-2">
<!-- 这个 form_obj 就是通过 locals() 传过来的 -->
{% for foo in form_obj %}
<div class="form-group">
<label for="{{ foo.id_for_label }}">{{ foo.label }}</label>
{{ foo }}
<p style="color: red">{{ foo.errors.0 }}</p>
</div>
{% endfor %}
<input type="submit" value="提交" class="btn btn-success">
</div>
</form>
校验规则
参数校验
class PersonForm(forms.Form):
name = forms.CharField(
max_length=16,
label="姓名",
)
age = forms.IntegerField(
# 该字段是否需要检验, false 为不检验
required=False
)
phone = forms.CharField(
# 最小长度和最大长度的检验
min_length=11,
max_length=11,
)
正则校验
from django.core.validators import RegexValidator
class BookForm(forms.Form):
phone = forms.CharField(
validators=[RegexValidator(r'^1[356789]\d{9}$', "手机号码格式有误")]
)
自定义校验
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
# 自定义的校验规则函数
def phone_validate(value):
# 用用户填写的手机号去数据库查找
is_exist = models.Book.objects.filter(phone=value)
if is_exist:
# 如果已经存在, 就不能注册
raise ValidationError("该手机号已经注册")
else:
return value
class BookForm(forms.Form):
phone = forms.CharField(
# validators 中可以插入多条验证规则
validators=[RegexValidator(r'^1[356789]\d{9}$', "手机号码格式有误"), phone_validate]
)
Hook 校验
class BookForm(forms.Form):
title = forms.CharField(
max_length=12,
label="书名",
)
pwd1 = forms.CharField(
label="pwd-1",
widget=forms.PasswordInput(
attrs={
"class": "form-control"
}
)
)
pwd2 = forms.CharField(
label="pwd-2",
widget=forms.PasswordInput(
attrs={
"class": "form-control"
}
)
)
# 局部钩子: clean_字段 方法
def clean_title(self):
# 从处理后的数据中拿到 title 的值
v = self.cleaned_data.get("title")
if "alex" in v:
raise ValidationError("包含敏感词 alex")
else:
return v
# 全局钩子
def clean(self):
# 可以取到 cleaned_data 中所有的数据进行对比校验
pwd1 = self.cleaned_data.get("pwd1")
pwd2 = self.cleaned_data.get("pwd2")
if pwd1 != pwd2:
# self.add_error("字段", "密码和确认密码不一致"), 这个是定义报错信息的位置
self.add_error("pwd2", "密码不相同")
else:
# 正常逻辑操作, 此处省略
pass