一、校验字段功能
1、reg页面准备
models
from django.db import models class UserInfo(models.Model): useranme = models.CharField(max_length=32) password = models.CharField(max_length=32) email = models.EmailField() telephone = models.CharField(max_length=32)
生成数据表
python manage.py makemigrations
python manage.py migrate
常规的form
路由层urls
from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('reg/', views.reg), ]
视图层views:
def reg(request): if request.method=='POST': print(request) pwd=request.POST.get('pwd') re_pwd=request.POST.get('re_pwd') if pwd==re_pwd: print(request.POST) return HttpResponse('注册成功') else: return HttpResponse('密码错误') return render(request,'reg.html')
模板层.html
<body> <form action="" method="post"> {% csrf_token %} <p>用户名<input type="text" name="user"></p> <p>密码<input type="password" name="pwd"></p> <p>确认密码<input type="password" name="re_pwd"></p> <p>电话<input type="number" name="tel"></p> <p>邮箱<input type="email" name="email"></p> <input type="submit"> </form> </body>
2、(form组件)定义规则
-----------------------------------------------------
print(request.POST):
{'user': 'yuan', 'pwd': '1234', 're_pwd': '1235', 'email': '123@qq.com', 'tel': '123'}
注意
总结校验字段功能
1、模板层form表单的name=‘属性值’必须与 form组件字段名称一致
2、定义class UserForm(forms.Form)
3、对前段传来的数据进行验证:form=UserForm(request.POST)
4、判断验证是否成功,布尔值form.is_valid()
5、print(form.cleaned_data)# 存放匹配成功的键值对 print(form.errors) # 存放 键:失败的信息
二、forms组件的渲染标签功能
方式一
views
from django.shortcuts import render, HttpResponse from django import forms # 导入forms组件 # 定义校验规则 class UserForm(forms.Form): name = forms.CharField(min_length=4, max_length=10) pwd = forms.CharField(min_length=4) re_pwd = forms.CharField(min_length=4) email = forms.EmailField() tel = forms.CharField() def reg_html(request): form = UserForm() return render(request, 'reg_html.html', locals())
reg.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body>
<h3>渲染标签功能1</h3>
<form action="" method="post">
{% csrf_token %}
<p>用户名
{{ form.user }}
</p>
<p>密码{{ form.pwd }}</p>
<p>确认密码{{ form.re_pwd}}</p>
<p>电话{{ form.tel }}</p>
<p>邮箱{{ form.email }}</p>
<input type="submit">
</form>
</body> </html>
可实现相同的功能
方式二
reg.html
<h3>渲染方式2</h3> <form action="" method="post"> {% csrf_token %} {% for field in form %} <div> {{ field.label }} {{ field }} </div> {% endfor %} </form>
可以自己设置label属性
方式3
<h3>渲染方式3</h3> <form action="" method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit"> </form>
三、显示error与重置输入信息功能
reg.html
<h3>渲染标签方式1</h3> <form action="" method="post" novalidate> {% csrf_token %} <p> {{ form.user.label }} {{ form.user }}<span>{{ form.user.errors.0 }}</span> </p> <p>{{ form.pwd.label }}{{ form.pwd }} <span>{{ form.pwd.errors.0 }}</span></p> <p>{{ form.re_pwd.label }}{{ form.re_pwd}}<span>{{ form.re_pwd.errors.0 }}</span></p> <p>{{ form.tel.label }}{{ form.tel }}<span>{{ form.tel.errors.0 }}</span></p> <p>{{ form.email.label }}{{ form.email }}<span>{{ form.email.errors.0 }}</span></p> <input type="submit"> </form>
views.py
def reg(request): if request.method=='POST': print(request) print(request.POST) form=UserForm(request.POST) print(form.is_valid()) # 返回布尔值 if form.is_valid(): print(form.cleaned_data) return HttpResponse('ok') else: print(form.cleaned_data)# 存放匹配成功的键值对 print(form.errors) # 存放 键:失败的信息 return render(request, 'reg.html', locals()) form=UserForm() return render(request, 'reg.html', locals())
说明:
四、forms组件的参数配置
1、参数提示参数设置
views.py
from django.forms import widgets ## 定义校验规则 class UserForm(forms.Form): # min_length最低为4位 user=forms.CharField(min_length=4,label='用户名' ,error_messages={'required':'该字段不为空', 'min_length': '不能少于4个字符'}, widget=widgets.TextInput(attrs={'class':'form-control'}))# 默认lable=User pwd=forms.CharField(min_length=4,label='密码',widget=widgets.PasswordInput(attrs={'class': 'form-control'}) ) re_pwd=forms.CharField(min_length=4,label='确认密码',widget=widgets.PasswordInput(attrs={'class': 'form-control'})) email=forms.EmailField(label='邮箱',widget=widgets.EmailInput(attrs={'class': 'form-control'}) , error_messages={'invalid': '格式错误'}) tel=forms.CharField(label='电话',widget=widgets.NumberInput(attrs={'class': 'form-control'}))
2、引入bootstrap模块优化界面
reg.html引入
<!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
reg.html
novalidate
<div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <h3>渲染标签方式1</h3> <form action="" method="post" novalidate> {% csrf_token %} <p> {{ form.user.label }} {{ form.user }}<span>{{ form.user.errors.0 }}</span> </p> <p>{{ form.pwd.label }}{{ form.pwd }} <span>{{ form.pwd.errors.0 }}</span></p> <p>{{ form.re_pwd.label }}{{ form.re_pwd}}<span>{{ form.re_pwd.errors.0 }}</span></p> <p>{{ form.tel.label }}{{ form.tel }}<span>{{ form.tel.errors.0 }}</span></p> <p>{{ form.email.label }}{{ form.email }}<span>{{ form.email.errors.0 }}</span></p> <input type="submit"> </form> </div> </div> </div>
五、forms组件的局部钩子
1、ValidationError:验证错误
models
from django.db import models class UserInfo(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=32) email = models.EmailField() tel = models.CharField(max_length=32)
froms组件,如何进行验证错误?
from django import forms from django.forms import widgets from app01.models import UserInfo from django.core.exceptions import ValidationError # 导入验证错误 ## 定义校验规则 class UserForm(forms.Form): # min_length最低为4位 user=forms.CharField(min_length=4,label='用户名' ,error_messages={'required':'该字段不为空', 'min_length': '不能少于4个字符'}, widget=widgets.TextInput(attrs={'class':'form-control'}))# 默认lable=User pwd=forms.CharField(min_length=4,label='密码',widget=widgets.PasswordInput(attrs={'class': 'form-control'}) ) re_pwd=forms.CharField(min_length=4,label='确认密码',widget=widgets.PasswordInput(attrs={'class': 'form-control'})) email=forms.EmailField(label='邮箱',widget=widgets.EmailInput(attrs={'class': 'form-control'}) , error_messages={'invalid': '格式错误'}) tel=forms.CharField(label='电话',widget=widgets.NumberInput(attrs={'class': 'form-control'})) # 局部钩子 def clean_user(self): val=self.cleaned_data.get('user') ret=UserInfo.objects.filter(useranme=val)# 数据库中的user if not ret: return ret else: raise ValidationError('该用户已经注册') # 验证错误
def reg(request):
if request.method=='POST':
print(request)
print(request.POST)
form=UserForm(request.POST)
print(form.is_valid()) # 返回布尔值
if form.is_valid():
print(form.cleaned_data)
return HttpResponse('ok')
else:
print(form.cleaned_data)# 存放匹配成功的键值对
print(form.errors) # 存放 键:失败的信息
return render(request, 'reg.html', locals())
form=UserForm()
return render(request, 'reg.html', locals())
forms组件源
模板层不变
提交与数据库姓名重名的结果
2、校验方法:clean_name 源码
在模板层加样式属性,让错误信息显示颜色
<span style="color: red">{{ form.pwd.errors.0 }}</span>
4、全局钩子校验
<form action="" method="post" novalidate>
{# novalidate 当提交表单时不对表单数据(输入)进行验证#}
模板
# forms组件 from django.forms import widgets wid_01=widgets.TextInput(attrs={"class":"form-control"}) wid_02=widgets.PasswordInput(attrs={"class":"form-control"}) from django.core.exceptions import ValidationError class UserForm(forms.Form): name=forms.CharField(max_length=32, widget=wid_01 ) pwd=forms.CharField(max_length=32,widget=wid_02) r_pwd=forms.CharField(max_length=32,widget=wid_02) email=forms.EmailField(widget=wid_01) tel=forms.CharField(max_length=32,widget=wid_01) # 局部钩子 def clean_name(self): val=self.cleaned_data.get("name") if not val.isdigit(): return val else: raise ValidationError("用户名不能是纯数字!") # 全局钩子 def clean(self): pwd=self.cleaned_data.get("pwd") r_pwd=self.cleaned_data.get("r_pwd") if pwd==r_pwd: return self.cleaned_data else: raise ValidationError('两次密码不一致!') def register(request): if request.method=="POST": form=UserForm(request.POST) if form.is_valid(): print(form.cleaned_data) # 所有干净的字段以及对应的值 else: clean_error=form.errors.get("__all__") return render(request,"register.html",locals()) form=UserForm() return render(request,"register.html",locals())
视图
<form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} <div> <label for="">{{ field.label }}</label> {{ field }} <span class="pull-right" style="color: red"> {% if field.label == 'R pwd' %} <span>{{ clean_error.0 }}</span> {% endif %} {{ field.errors.0 }} </span> </div> {% endfor %} <input type="submit" class="btn btn-default"> </form>
--------------------------------
# 直接覆盖父类的clean方法, 全局钩子 def clean(self): pwd = self.cleaned_data.get("pwd") r_pwd = self.cleaned_data.get("r_pwd") # 先判断是否接受到pwd,r_pwd的值 if pwd and r_pwd: if pwd == r_pwd: return self.cleaned_data else: raise ValidationError("两次密码不一致") else: return self.cleaned_data
总结:forms组件解耦,调用冲突
把form组件内容单独放一个模块中,不要放在views.py中