首先定義一個表單類(繼承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裏面字段參數的逗號等格式,重啓下就行了