forms组件
1、校验字段功能(最核心功能)
示例1:
在服务端进行格式校验
-------视图函数里--------
from django import forms
class UserForm(forms.Form): #新建一个校验类
name = forms.CharField(min_length) #必须为字符串,最小4位
email = forms.EmailField() #邮箱校验
def register(request):
# 字典的键必须跟校验类里的字段一样
form=UserForm({"name":"yuan","email":"123"})
# 开始校验,所有值校验通过返回True
# 字典里有多少个无所谓,只要校验类里的字段通过就是True
bool = form.is_valid()
# cleaned_data 这里面放所有校验通过的键值
form.cleaned_data
# errors 这里面放所有未通过的键值 是仿字典类型
#例如name没通过,要取errors里的错误信息:form.errors["name"][0]
form.errors
return HttpResponse(request, "ok")
示例2:
def register(request):
#校验类字段要跟前端form表单一样
form=UserForm(request.POST)
if form.is_valid():
clean = form.cleaned_data
else:
clean = form.cleaned_data
errors = form.errors
总结:
1.前端form表单内的需要校验的值,要跟后端校验类的字段一致
2. is_valid() 、 cleaned_data、 errors各自含义
forms组件的渲染标签功能:
1、渲染方式一
先写后端校验类,再在前端渲染,charFiled渲染成input标签:
class UserForm(forms.Form):
name = forms.CharField(min_length=4)
pwd = forms.CharField(min_length=4)
r_pwd = forms.CharField(min_length=4)
email = forms.EmailField()
tel = forms.CharField()
def reg(request):
form = UserForm()
return render("reg_html",{"form":form})
为了方便,Django可以在前端按照后端写的校验类进行渲染
<form>
{% csrf_token %}
用户名:{{ form.name }}
密码:{{ form.pwd }}
确认密码:{{ form.r_pwd }}
邮箱:{{ form.email }}
电话:{{ form.tel }}
<input type="submit">
</form>
2、渲染方式二:如果字段很多
class UserForm(forms.Form):
name = forms.CharField(min_length=4, label="用户名")
pwd = forms.CharField(min_length=4, label="密码")
r_pwd = forms.CharField(min_length=4, label="确认密码")
email = forms.EmailField(label="邮箱")
tel = forms.CharField(label="电话")
def reg(request):
form = UserForm()
return render("reg_html",{"form":form})
-------------------------------
<form>
{% csrf_token %}
{% for field in form%}
<div>
<label for="">{{ field.label }}</label>
{{ field }}
</div>
{% endfor %}
<input type="submit">
</form>
3、渲染方式三,自己搞着玩可以
<form>
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
4、渲染错误信息
def register(request):
if request.method=="POST":
form=UserForm(request.POST)
if form.is_valid():
clean = form.cleaned_data
else:
clean = form.cleaned_data
errors = form.errors
# 注意:这里返回的页面可以保存用户上次已经填过的数据,还包括错误信息
return render("reg_html",{"form":form})
#如果是get请求,渲染空form页面
form=UserForm()
return render(request,"reg_html",{"form":form})
-----------------
<form>
{% csrf_token %}
{% for field in form%}
<div>
<label for="">{{ field.label }}</label>
{{ field }} <span>{{ field.errors.0 }}</span>
</div>
{% endfor %}
<input type="submit">
</form>
---------------------
form组件--校验类的参数
改渲染的标签类型为password:widgets
改错误提示信息:error_messages
如果需要给渲染的标签加样式类,加属性键值对,什么都行:widget=widgets.TextInput(attrs={"class":"form-control"})
from django.forms import widgets
class UserForm(forms.Form):
name = forms.CharField(min_length=4, label="用户名", error_messages={"required":"不能为空","invalid":"格式错误"})
pwd = forms.CharField(min_length=4, label="密码",widget=widgets.PasswordInput(attrs={"class":"form-control"}))
r_pwd = forms.CharField(min_length=4, label="确认密码")
email = forms.EmailField(label="邮箱",widget=widgets.TextInput(attrs={"class":"form-control"}))
tel = forms.CharField(label="电话")
forms组件校验的局部钩子(要看源码理解)
校验第二层:clean_xx方法,校验通过返回该值,否则抛ValidationError异常
from django.core.exceptions import ValidationError
class UserForm(forms.Form):
name = forms.CharField(min_length=4, label="用户名")
pwd = forms.CharField(min_length=4, label="密码")
r_pwd = forms.CharField(min_length=4, label="确认密码")
email = forms.EmailField(label="邮箱")
tel = forms.CharField(label="电话")
#该功能验证用户名是否已被注册
def clean_name(self):
name = self.cleaned_data.get("name")
ret = UserInfo.objects.filter(name=name)
if not ret:
return name
else:
#只能抛这个错误
raise ValidationError("该用户已注册")
全局钩子--校验form表单两次密码输入是否一致:
在校验类里,覆盖父类clean方法
获取全局钩子错误:form.errors.get("__all__")[0]
def clean():
pwd=self.cleaned_data.get(‘pwd‘)
r_pwd=self.cleaned_data.get(‘r_pwd‘)
if pwd and r_pwd:
# pwd跟r_pwd之前的校验已通过,才验证全局钩子
if pwd==r_pwd:
return self.cleaned_data
else:
raise ValidationError(‘两次输入密码不一致‘)
else:
return self.cleaned_data
原文:https://www.cnblogs.com/staff/p/10735347.html