Django——froms渲染错误信息,参数配置,局部钩子和全局钩子
一、froms渲染错误信息
url.py settings.py 略
views.py #视图函数
from django.shortcuts import render,redirect,HttpResponse from app01 import myforms def register(request): if request.method=='GET': form=myforms.MyForm() return render(request, 'register.html',{'form':form}) else: form=myforms.MyForm(request.POST) if form.is_valid(): # 存数据库 print('-----',form.cleaned_data) return redirect('http://www.baidu.com') else: err=form.errors.get('__all__') print(form.errors.get('__all__')) #{name:[],age:[],__all__:[]} return render(request, 'register.html',{'form':form,'err':err})
myforms.py
需要储备的知识:
forms组件参数配置
# 定制模板中的显示样式,及配置类 # widget=widgets.PasswordInput(attrs={'class': 'form-control'}) # 错误信息中文显示 error_messages={'min_length': '太短了小伙子'}
class MyForm(forms.Form): # 校验这个字段,最大长度是32,最小长度是3 name = forms.CharField(required=False, max_length=32, min_length=3, label='用户名', widget=widgets.TextInput(attrs={'class': 'form-control'}), error_messages={'min_length': '太短了小伙子'}) password = forms.CharField(required=False, max_length=32, min_length=3, label='密码', widget=widgets.PasswordInput(attrs={'class': 'form-control'}), error_messages={'min_length': '太短了小伙子'}) re_password = forms.CharField(required=False, max_length=32, min_length=3, label='确认密码', widget=widgets.PasswordInput(attrs={'class': 'form-control'}), error_messages={'min_length': '太短了小伙子'}) email = forms.EmailField(label='邮箱', error_messages={'required': '小伙子,这个必填'}, widget=widgets.TextInput(attrs={'class': 'form-control'})) age = forms.IntegerField(max_value=200, min_value=0, label='年龄', widget=widgets.TextInput(attrs={'class': 'form-control'})) text = forms.CharField(label='个人简介', widget=widgets.Textarea(attrs={'class': 'form-control'})) date = forms.CharField(label='出生日期', widget=widgets.DateInput(attrs={'class': 'form-control'}))
代码:
from django import forms from django.forms import widgetsclass MyForm(forms.Form): # 校验这个字段,最大长度是32,最小长度是3 name = forms.CharField(required=False, max_length=32, min_length=3, label='用户名', widget=widgets.TextInput(attrs={'class': 'form-control'}), error_messages={'min_length': '太短了小伙子'}) password = forms.CharField(required=False, max_length=32, min_length=3, label='密码', widget=widgets.PasswordInput(attrs={'class': 'form-control'}), error_messages={'min_length': '太短了小伙子'}) re_password = forms.CharField(required=False, max_length=32, min_length=3, label='确认密码', widget=widgets.PasswordInput(attrs={'class': 'form-control'}), error_messages={'min_length': '太短了小伙子'}) email = forms.EmailField(label='邮箱', error_messages={'required': '小伙子,这个必填'}, widget=widgets.TextInput(attrs={'class': 'form-control'})) age = forms.IntegerField(max_value=200, min_value=0, label='年龄', widget=widgets.TextInput(attrs={'class': 'form-control'}),error_messages={'max_value': '输入数字过大','min_value': '输入数字太小'}) text = forms.CharField(label='个人简介', widget=widgets.Textarea(attrs={'class': 'form-control'})) date = forms.CharField(label='出生日期', widget=widgets.DateInput(attrs={'class': 'form-control'}))
register.html #模板文件
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> <title>Document</title> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <h1>模板渲染</h1> <form action="" method="post" novalidate> {# novalidate表示前端不校验了#} {% for foo in form %} <div class="form-group"> <label for="">{{ foo.label }}</label> {{ foo }} <span class="text-danger pull-right">{{ foo.errors }}</span> {# pull-right表示靠右#} </div> {% endfor %} <div class="text-center"> <input type="submit" value="提交" class="btn btn-danger"> <span class="text-primary">{{ err }}</span> </div> </form> </div> </div> </div> </body> </html>
二、局部钩子
更复杂的校验,姓名不能以sb开头
局部钩子(写一个方法,方法名叫 clean_字段名)
一旦能走到这个方法中,说明前面的校验已经通过了
#使用步骤 # 1 在自定义的Form类中写 clean_字段名 # 2 取出字段的真正值,name=self.cleaned_data.get('name') # 3 判断自己的规则,如果判断失败,抛出ValidationError # 4 如果通过,return name def clean_name(self): # name对应的值,如何取到? name = self.cleaned_data.get('name') if name.startswith('sb'): # 不让校验通过 raise ValidationError('不能以sb开头') else: # 校验通过,返回name return name
三、全局钩子
校验两次密码是否相同
## 全局钩子函数 # 只要走到它,前面,字段自己的校验和局部钩子校验都通过了 def clean(self): # name=self.cleaned_data.get('name') # print(name) password = self.cleaned_data.get('password') re_password = self.cleaned_data.get('re_password') if password == re_password: return self.cleaned_data # return {'lqz':"nb"} else: raise ValidationError('两次密码不一致')