(32)forms组件(渲染自建规则:局部钩子函数和全局钩子函数)

时间:2023-12-30 12:35:02

要达成渲染自建规则

1、局部钩子函数(某个字段,自定意义规则,不如不能以sb开头,数据库已存在等)

2、全局钩子函数(校验两次密码是否一致)

3、使用css样式

register.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
<title>注册页面</title>
<style>
.errors {
color: red;
margin-left: 20px;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-offset-3 col-md-6">
<h1>forms渲染页面,实现局部刷新</h1>
<form action="" method="post" novalidate>
{% csrf_token %}
{% for form in forms %}
<p>{{ form.label }}:{{ form }}<span class="errors">{{ form.errors.0 }}</span></p>
{% endfor %}
<input type="submit" value="提交"><span class="errors">{{ error }}</span>
</form>
</div>
</div>
</div> </body>
</html>

views.py

from django.shortcuts import render,HttpResponse
from django.core.exceptions import ValidationError
from django import forms
from django.forms import widgets #导入这个模块就是将前端表单里的类型修改,从后端修改前端的输入框类型 class RegForms(forms.Form):
# widget 就是定义前端输入框的类型,后面的引用就是widget后面的参数是指定输入框的格式,TextInput是一个类,传入的参数attrs是一个字典,可以利用这个参数给前端的标签取类名或者id名等等来实现引用bootstrap的样式
name = forms.CharField(min_length=3,max_length=8,label='用户名',error_messages={'min_length':'用户名太短','max_length': '用户名太长了','required':'该字段必填'},widget=widgets.TextInput(attrs={'class':'form-control'}))
pwd = forms.CharField(min_length=3,max_length=8,label='密码',error_messages={'min_length':'用户名太短','max_length': '用户名太长了','required':'该字段必填'},widget=widgets.PasswordInput(attrs={'class':'form-control'}))
re_pwd = forms.CharField(min_length=3,max_length=8,label='确认密码',error_messages={'min_length':'用户名太短','max_length': '用户名太长了','required':'该字段必填'},widget=widgets.PasswordInput(attrs={'class':'form-control'}))
email = forms.EmailField(label='邮箱',error_messages={'invalid':'格式不是邮箱格式','required':'该字段必填'},widget=widgets.EmailInput(attrs={'class':'form-control'})) '''局部校验,就是校验某个字段'''
'''写法固定,就是clean_字段名,就是重写字段校验规则的固定写法'''
def clean_name(self):
# self就是当前forms对象,cleand_data就是清洗后的数据,从字典中取出name
name = self.cleaned_data.get('name')
# 如果以sb为开头
if name.startswith('sb'):
# 这里要抛一个异常,而且是一个ValidationError,这个ValidationError是一个模块要导入
raise ValidationError('不能以sb开头')
else:
return name '''全局钩子函数(校验两次密码不一致),用clean函数这个是固定的,获取清洗后的数据,然后进行判断用raise抛异常即可'''
def clean(self):
pwd = self.cleaned_data.get('pwd') # 从清洗后的数据中获取pwd
re_pwd = self.cleaned_data.get('re_pwd')
if pwd == re_pwd:
return self.cleaned_data
else:
raise ValidationError('两次密码不一致') def register(request):
if request.method == 'GET':
forms = RegForms()
error=''
elif request.method == 'POST':
forms = RegForms(request.POST)
if forms.is_valid():
print('这里就是清洗后的数据: ',forms.cleaned_data)
return HttpResponse('注册成功')
else:
errors_dic = forms.errors
print(errors_dic)
print('这里就是错误的数据: ',forms.errors.as_data)
# 这里获取全局钩子函数的错误信息,就要用__all__,然后全局的错误信息可能是多个的,所以取最近的一个就是索引位是0的位置
error = forms.errors.get('__all__')[0] return render(request,'register.html',{'forms':forms,'error':error})