利用django form組件+ajax實現用戶認證

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