利用django form组件+ajax实现用户认证
首先定义一个表单类(继承forms.Form):
登录后复制
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
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
这里把里面的属性值设置为跟前端post请求中的参数值一样,这样当实例化form类的时候只要把post请求传递进去:
data = regform(data=request.POST)
form类的字段格式简单易懂:
登录后复制
要检测字段名=forms.字段类型(各种检测参数)
检测参数比较常用的有:
max_length:最大长度
min_length:最小长度
error_messages:自定义错误信息,格式:检测名+自定义的错误信息
widget:html插件
…
form组件主要功能就是自定义的正则匹配(做验证用)+html插件功能(前端展示)
如果form组件自带的检测参数不足以满足需求,form组件还允许自定义函数:
局部检测:clean_字段名(比如定义了age,想再检测age,就在form类里面定义,clean_age()函数,若返回错误,可以raise对应错误类型,默认只能捕捉ValidationError,若正确,返回age即可)
全局检测函数:clean()函数
form类在实例并不检测,只有在执行is_valid()方法时才开始检测,检测顺序就是: form的规则–>clean_局部函数–>clean函数
view部分:
登录后复制
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))
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
regester.html部分
登录后复制
<!DOCTYPE html>
<html >
<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" >
<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" >
<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" >
<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" >
<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" >
<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" >
<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" >#}
{# <img src="image/verify_code.jpg" >#}
{# </td>#}
</tr>
<tr>
<td colspan="2" align="center" >
<div >注册</div>
{# <input type="submit" value="注册" >#}
</td>
</tr>
</table>
</form>
</div>
</div>
<div class="rg_right">
<p>已有账号?<a rel="nofollow" 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>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
debug:
登录后复制
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里面字段参数的逗号等格式,重启下就好了
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.