首先定义一个表单类(继承forms.Form):css
from django import forms from django.core import validators from django.forms import CharField from cdnpanel.models import User from django.core.exceptions import ValidationError mobile_validator = validators.RegexValidator(r"^1[3-9]\d{9}$", "手机号码格式不正确") class regform(forms.Form): username = forms.CharField( max_length=8, min_length=2, required=True, error_messages={"max_length": "最大长度不能超过8", "min_length": "最小长度不能小于2", "required": "用户名不能为空"}, ) password = forms.CharField( min_length=8, required=True, error_messages={"min_length": "最小长度不能小于8", "required": "密码不能为空"}, ) email = forms.EmailField(error_messages={"required": "邮箱不能为空"}) name = forms.CharField(max_length=8, required=False) tel = forms.CharField(max_length=11, min_length=11, validators=[mobile_validator, ], error_messages={"min_length": "手机号长度有误", "max_length": "手机号长度有误", "required": "手机号不能为空"}) gender = forms.ChoiceField( choices=(('male', "女"), ("female", "女")), error_messages={"required": "性别不能为空"}) birthday = forms.DateField( error_messages={"required": "生日不能为空"} ) # 自定义验证,格式:clean_列名 # 这是局部验证,由于不肯定其余参数是否放在cleaned_data里面 def clean_username(self): username = self.cleaned_data.get("username") if User.objects.filter(username=username).exists(): raise ValidationError("用户已存在") else: return username # 全局验证,以上的步骤都执行完,最后执行此函数 def clean(self): pass
这里把里面的属性值设置为跟前端post请求中的参数值同样,这样当实例化form类的时候只要把post请求传递进去:
data = regform(data=request.POST)
form类的字段格式简单易懂:html
要检测字段名=forms.字段类型(各类检测参数)
检测参数比较经常使用的有:
max_length:最大长度
min_length:最小长度
error_messages:自定义错误信息,格式:检测名+自定义的错误信息
widget:html插件
...前端
form组件主要功能就是自定义的正则匹配(作验证用)+html插件功能(前端展现)jquery
若是form组件自带的检测参数不足以知足需求,form组件还容许自定义函数:ajax
局部检测:clean_字段名(好比定义了age,想再检测age,就在form类里面定义,clean_age()函数,若返回错误,能够raise对应错误类型,默认只能捕捉ValidationError,若正确,返回age便可)
全局检测函数:clean()函数django
form类在实例并不检测,只有在执行is_valid()方法时才开始检测,检测顺序就是: form的规则-->clean_局部函数-->clean函数json
view部分:ide
from django.core.exceptions import ValidationError from django.db import IntegrityError from django.shortcuts import redirect, render, HttpResponse from cdnpanel.models import User, Domain, Proxy from cdnpanel.pager import Pagination from cdnpanel.def_form import regform def register(request): if request.method == "GET": return render(request, 'register.html') else: if request.is_ajax(): data = regform(data=request.POST) ajax_rsp = {"status": "err", "msg": None} if data.is_valid(): ajax_rsp["status"] = "ok" User.objects.create(**data.cleaned_data) else: ajax_rsp['status'] = "err" ajax_rsp["msg"] = data.errors return HttpResponse(json.dumps(ajax_rsp))
regester.html部分函数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注册页面</title> <!-- 引入格式文件--> <link rel="stylesheet" href="/static/css/register.css"> <style> .err{ color: red; } </style> </head> <body> <div class="rg_layout"> <div class="rg_left"> <p>新用户注册</p> <p>USER REGISTER</p> </div> <div class="rg_center"> <div class="rg_form"> <form action="/test" method="post"> {% csrf_token %} <table> <tr><!--label 标签的做用是当点击文字也会跳到文本输出框--> <!--for属性与ID属性对应规定 label 绑定到哪一个表单元素。--> <td class="td_left"><label for="username">用户名</label> </td> <td class="td_right"><input type="text" name="username" id="username"> <span class="username_err err"></span> </td> </tr> <tr> <td class="td_left"><label for="password">密码</label> </td> <td class="td_right"><input type="password" name="password" id="password"> <span class="password_err err"></span> </td> </tr> <tr><!--label 标签的做用是当点击文字也会跳到文本输出框--> <td class="td_left"><label for="email">email</label> </td> <td class="td_right"><input type="email" name="email" id="email"> <span class="email_err err"></span> </td> </tr> <tr> <td class="td_left"><label for="name">姓名</label> </td> <td class="td_right"><input type="text" name="name" id="name"> <span class="name_err err"></span> </td> </tr> <tr> <td class="td_left"><label for="tel">手机号</label> </td> <td class="td_right"><input type="text" name="tel" id="tel"> <span class="tel_err err"></span> </td> </tr> <tr> <td class="td_left">性别</td> <td class="td_right"> <input type="radio" name="gender" value="male">男 <input type="radio" name="gender" value="female">女 <span class="gender_err err"></span> {# 加个span标签显示错误信息,默认为空值,err样式赋予红色字体 #} </td> </tr> <tr> <td class="td_left"><label for="birthday">出生日期</label> </td> <td class="td_right"><input type="date" name="birthday" id="birthday"> <span class="birthday_err err"></span> </td> </tr> <tr> {# <td class="td_left"><label for="checkcode">验证码</label> </td>#} {# <td class="td_right">#} {# <input type="text" name="username1" id="checkcode">#} {# <img src="image/verify_code.jpg" id="img_check">#} {# </td>#} </tr> <tr> <td colspan="2" align="center" > <div id="btn_sub" >注册</div> {# <input type="submit" value="注册" id="btn_sub">#} </td> </tr> </table> </form> </div> </div> <div class="rg_right"> <p>已有帐号?<a href="/login">当即登陆</a></p> </div> </div> </body> <script src="/static/js/jquery-3.5.1.min.js"> </script> <script> $("#btn_sub").click(function (){ var data={} data['username']=$("#username").val() data['password']=$("#password").val() data['email']=$('#email').val() data['birthday']=$('#birthday').val() data['name']=$('#name').val() data['tel']=$('#tel').val() data['gender']=$('input:radio[name="gender"]:checked').val(); $.ajax({ data:data, dataType:"json", "type":"POST", "url":'/register', "success":function (arg) { if (arg.status == "ok") { window.location.replace("/login") } else { var err=arg.msg for ( x in err) { $("."+x+"_err").text(err[x]) } console.log("aaa") } } }) }) </script> </html>
debug:post
1.forms的errors默认是'django.forms.utils.ErrorDict 数据格式 返回默认使用as_ul方法,能够改成as_json data=regform(request.POST) data.is_valid() data.errors.as_json() 2.form表单choies报错:famale is not one of the available choices 排查后发现,前端传递的值有问题,把female写成了famale 3.form组件里面的password字段不能识别 缘由:未知 解决:检查统一form里面字段参数的逗号等格式,重启下就行了