121.自定义验证器
自定义验证器:
有时候我们需要从数据库中提取数据进行验证,这个时候如果还是采用已经定义好的验证器就不能够实现我们想要的功能了。比如我们在注册的时候要验证该手机号或者是邮箱之前是否已经注册过了。如果已经注册过了,就不能够再次进行注册了。这个时候我们就需要对数据库中的手机字段进行验证了。对某个字段进行验证的方式就是,定义一个方法,这个方法的名字的定义规则就是clean_fieldname.如果验证失败,那么就抛出一个错误,如果没有找到相同的手机号就正常情况下返回一个手机号,代表已经通过了验证。
(1)比如,在注册的时候我们需要输入用户名手机号,密码以及确认密码四个字段的内容,同时需要对手机号是否存在数据库中进行判断,并且对密码的长度和两次密码的是否相同进行判断。那么就可以通过以下代码实现:
forms.py文件中定义form表单字段,并且自定义验证器,示例代码如下:
from django import forms
from djang.core import validators
from .models import User
class RegisterForm(forms.Form):
username = forms.CharField(max_length=100,error_messages={'invalid': '输入的username是无效的'})
# 注意这里定义的验证器参数validators所对应的是列表,一个可以迭代的对象。
telephone = forms.CharField(validators=[validators.RegexValidator(r"1[345678]\d{9}", message='请输入正确的手机号码')])
pwd1 = forms.CharField(max_length=24, min_length=6, error_messages={'invalid':'您输入的密码长度不符合要求'})
pwd2 = forms.CharField(max_length=24, min_length=6, error_messages={'invalid':'您输入的密码长度不符合要求'})
<!--对telephone字段进行自定义验证器:验证数据库中是否已经存在当前传递过来的手机号-->
<!--函数名定义规则:clean_fieldname-->
def clean_telephone(self):
<!--需要调用父类的super()方法,获取当前对象的所有参数值-->
telephone = self.super().cleaned_data.get('telephone')
<!--使用exists()查看数据库中与telephone是否有相同的telephone,如果有的话,抛出一个异常;如果为False的话,就返回telephone-->
exists = User.objects.filter(telephone=telephone).exists()
if exists:
raise forms.ValidationError('%s您输入的手机号已经注册过了,请确定后再输入。'%telephone)
return telephone
<!--判断form的多个字段时,可以通过重写clean方法-->
def clean(self):
clean_data = super().clean()
pwd1 = clean_data.get('pwd1')
pwd2 = clean_data.get('pwd2')
<!--对两次获取的密码进行对比,如果二者相同的话,就可以正确的返回clean_data;否者的话,就要抛出一个异常信息。-->
if pwd1 != pwd2:
raise forms.ValidationError('您两次输入的密码不相同,请确认!')
return clean_data
在views.py文件定义对应的类视图,示例代码如下:
from django.views import View
from .forms import RegisterForm
from .models import User
from django.http import HttpResponse
from django.shortcuts import render
class register_view(View):
def get(self, request):
forms = RegisterForm()
return render(request, 'register.html',context={'forms':forms})
def post(self, request):
forms = RegisterForm(request.POST)
<!--判断定义的forms表单是否符合要求,同时在执行is_valid()判断的时候,会自动调用在forms.py文件中自定义的验证器,进行相应的判断。-->
if forms.is_valid():
username = forms.cleaned_data.get('username')
telephone = forms.cleaned_data.get('telephone')
pwd1 = forms.cleaned_data.get('pwd1')
pwd2 = forms.cleaned_data.get('pwd2')
User.objects.create(username=username, telephone=telephone,pwd1=pwd1, pwd2=pwd2)
return HttpResponse('Add user successful')
else
<!--注意,一定要打印出forms的错误信息,否则的话,我们定义的验证器中抛出的异常就不能够显示,就达不到所想要的效果了-->
print(forms.errors.get_json_data())
return HttpResponse('Fail user lose')
在models.py文件中定义相应的User模型,示例代码如下:
from django.db import models
class User(models.Model):
username = models.CharField(max_length=100)
telephone = models.CharField(max_length=100,unique=True)
pwd1 = models.CharField(max_length=24)
pwd2 = models.CharField(max_length=24)
在APP中的urls.py文件中进行映射:
from django.urls import path
from .views import Addview, register_view
app_name = 'validator'
urlpatterns = [
path('', Addview.as_view(), name='add'),
path('register/', register_view.as_view(), name='register'),
]
在项目的urls.py文件中进行映射,示例代码如下:
from django.urls import path, include
urlpatterns = [
path('front/', include('front.urls')),
path('validator/', include('validator.urls')),
]
在register.html中的表单定义如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
<table>
<tr>
<td>姓名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>手机号:</td>
<td><input type="text" name="telephone"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="pwd1"></td>
</tr>
<tr>
<td>确认密码:</td>
<td><input type="password" name="pwd2"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="提交"></td>
</tr>
</table>
</form>
</body>
</html>
始于才华,忠于颜值;每件事情在成功之前,看起来都是天方夜谭。一无所有,就是无所不能。