Django Form組件 ---- 第20章

1. Form組件的功能

對用戶提交表單數據進行校驗、保留上次輸入內容。

2. 數據校驗

Form組件對Form表單的方式提交的數據進行校驗:

login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
</head>
<body>
<div class="container" style="margin-top: 10px">
    <div class="row">
        <div class="col-md-4 col-md-offset-4">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    登錄
                </div>
                <div class="panel-body">
                    <form action="/login.html/" method="POST" name="loginForm">
                        <div class="form-group">
                            <label for="name">用戶名</label>
                            <input type="text" class="form-control" name="name" placeholder="請輸入用戶名">
                            <div style="color: red;font-weight: bold">{{ obj.errors.name.0 }}</div>
                        </div>
                        <div class="form-group">
                            <label for="">密碼</label>
                            <input type="password" class="form-control" name="pwd" placeholder="請輸入密碼">
                            <div style="color: red;font-weight: bold">{{ obj.errors.pwd.0 }}</div>
                        </div>
                        {% csrf_token %}
                        <button type="submit" class="btn btn-primary">登錄</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

在這裏插入圖片描述

class LoginForm(Form):
    name = fields.CharField(
        required=True,
        min_length=6,
        max_length=20,
        error_messages={
            'required': '用戶名不能爲空!',
            'min_length': '用戶名長度不能小於6!',
            'max_length': '用戶名長度不能大於20!'
        }
    )
    pwd = fields.CharField(
        required=True,
        min_length=6,
        max_length=20,
        error_messages={
            'required': '密碼不能爲空!',
            'min_length': '密碼長度不能小於6!',
            'max_length': '密碼長度不能大於20!'
        }
    )
    
def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    else:
        obj = LoginForm(request.POST)
        """
        1、LoginForm實例化時
        self.field={'name':正則表達式,'pwd':正則表達式}
        2、循環self.field
        for k,v in self.field.items():
            input_value = request.POST.get(k)
            正則表達式和input_value進行匹配
        """
        if obj.is_valid():
            # 校驗通過的數據
            print(obj.cleaned_data)
        else:
        	print(obj.errors, type(obj.errors))  # <class 'django.forms.utils.ErrorDict'>
            """
            <ul class="errorlist">
                <li>name
                    <ul class="errorlist">
                        <li>用戶名不能爲空</li>
                    </ul>
                </li>
                <li>pwd
                    <ul class="errorlist">
                        <li>用戶名不能爲空</li>
                    </ul>
                </li>
            </ul>
            """
        return render(request, 'login.html', {'obj': obj})

上面是Form組件校驗以Form表單的方式的提交數據,下面是以AJAX的方式提交數據:

login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
    <link rel="stylesheet" href="../static/css/bootstrap.min.css">
</head>
<body>
<div class="container" style="margin-top: 10px">
    <div class="row">
        <div class="col-md-4 col-md-offset-4">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    登錄
                </div>
                <div class="panel-body">
                    <form id="form" action="" method="POST" name="loginForm" novalidate>
                        <div class="form-group">
                            <label for="name">用戶名</label>
                            <input type="text" class="form-control" name="name" placeholder="請輸入用戶名">
                            <div style="color: red;font-weight: bold">{{ obj.errors.name.0 }}</div>
                        </div>
                        <div class="form-group">
                            <label for="">密碼</label>
                            <input type="password" class="form-control" name="pwd" placeholder="請輸入密碼">
                            <div style="color: red;font-weight: bold">{{ obj.errors.pwd.0 }}</div>
                        </div>
                        <div class="form-group">
                            <label for="">郵箱</label>
                            <input type="email" class="form-control" name="email" placeholder="請輸入密碼">
                            <div style="color: red;font-weight: bold">{{ obj.errors.email.0 }}</div>
                        </div>
                        <div class="form-group">
                            <label for="">手機號</label>
                            <input type="text" class="form-control" name="phone" placeholder="請輸入密碼">
                            <div style="color: red;font-weight: bold">{{ obj.errors.phone.0 }}</div>
                        </div>
                        {% csrf_token %}
                        <button id="loginBtn" type="button" class="btn btn-primary">登錄</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<script src="../static/js/jquery-3.5.1.min.js"></script>
<script>
    $(function () {
        ajaxLogin();
    })

    function ajaxLogin() {
        $('#loginBtn').click(function () {
            var formData = $('#form').serialize();//會忽略字段左右的空格
            console.log(formData)//name=thanlon&pwd=123456&[email protected]&phone=18523332005&csrfmiddlewaretoken=xxx
            $.ajax({
                url: '/login.html/',
                type: 'post',
                data: formData,
                dataType: 'json',
                success: function (arg) {
                    console.log(arg);//{"status": 0, "msg": null}
                    if (arg.status) {
                        //location.href = 'https://www.baidu.com'
                    } else {
                        //清除之前的錯誤提示信息
                        $('.clearTag').remove();
                        console.log(arg.msg)//對象類型
                        $.each(arg.msg, function (index, value) {
                            /**
                             * alert(index);//錯誤字段,pwd
                             * alert(value);//錯誤消息,如This field is required.
                             * alert(typeof (index)) //string
                             * alert(typeof (value))//object
                             * alert(value[0])
                             */
                            var tag = document.createElement('span');
                            tag.innerHTML = value[0];
                            tag.className = 'clearTag';
                            $('#form').find('input[name="' + index + '"]').after(tag);
                        })
                    }
                }
            })
        })
    }
</script>
</html>

views.py:

from django.forms import Form, fields
from django.shortcuts import render, HttpResponse
from app01 import models
import json

class LoginForm(Form):
    name = fields.CharField()
    pwd = fields.CharField()
    email = fields.EmailField()
    phone = fields.RegexField('185\d+')

def ajax_login(request):
    if request.method=='GET':
        return render(request,'login.html')
    ret = {'status': True, 'msg': None}
    print(type(json.dumps(ret)))  # <class 'str'>
    obj = LoginForm(request.POST)
    if obj.is_valid():
        print(obj.cleaned_data)#{'name': 'thanlon', 'pwd': '123456', 'email': '[email protected]', 'phone': '18523332005'}
    else:
        print(obj.errors)  # obj.errors是對象
        ret['status'] = False
        ret['msg'] = obj.errors
    return HttpResponse(json.dumps(ret))  # <class 'str'>

在這裏插入圖片描述

AJAX僅用來驗證功能,Form可以驗證功能也可以生成HTML標籤。

3. 常用字段和參數
Field:
	required = True,  # 是否允許爲空
	label = None,  # 用於生成Label標籤
	initial = None,  # 初始值
	help_text = '',  # 幫助信息(在標籤旁邊顯示)
	error_messages = {},  # 錯誤信息{'invalid':'格式錯誤'}
	show_hidden_initial = None,  # 是否在當前插件後面再加上一個隱藏的且具有默認值的插件(可用於檢驗兩次輸入是否一致)
	validators = [],  # 自定義驗證規則
	localize = False,  # 是否支持本地化
	disabled = False,  # 是否可以編輯
	label_suffix = None,  # Label內容後綴
	widget = None,  # HTML插件

CharField類和IntegerField 類都繼承Field類,但是除了具有Field中的所有屬性之外還有其它屬性:

CharField(Field):
    min_length = None,
    max_length = None,
    strip = True,  # 是否移除空白
    
IntegerField(Field):
	min_length = None,
    max_length = None,

DecimalField(IntegerField):
    max_value=None,  # 最大值
    min_value=None,  # 最小值
    max_digits=None,  # 總長度
 
BaseTemporalField(Field)
	input_formats=None,  # 時間格式化

BaseTemporalField(Field)
	input_formats=None,  # 時間格式化

DateField(BaseTemporalField): # 格式:2020-10-12
TimeField(BaseTemporalField): # 格式:12:50
DateTimeField(BaseTemporalField): # 格式:2020-10-12 12:50

DurationField(Field): # 時間間隔:%d %H:%M:%S.%f

RegexField(CharField):
	regex='185\d+',
	max_length=None,
    min_length=None,
    error_messages={}

EmailField(CharField)
URLField(CharField)
SlugField(CharField)
GenericIPAddressField(CharField)
4. 保留上次輸入內容

Form表單的方式提交數據,頁面會刷新會失去提交的內容。AJAX方式提交時頁面不刷新,上次輸入內容自動保存。使用Form表單提交數據保存上次輸入的內容也是可以實現的,需要應用到Form組件提供的第二個功能 生成HTML標籤。只需要在 input 框中加入驗證通過的數據 obj.cleaned_data

views.py:

class LoginForm(Form):
    name = fields.CharField(
        label='用戶名',
    )
    pwd = fields.CharField(
        label='密碼',
    )
    email = fields.EmailField(
        label='郵箱'
    )
    phone = fields.RegexField(
        label='手機號',
        regex='185\d+',
    )

def ajax_login(request):
    if request.method == 'GET':
        obj = LoginForm()
        return render(request, 'login.html',{'obj': obj})
    else:
        obj = LoginForm(request.POST)
        if obj.is_valid():
            print(obj.cleaned_data)
        else:
            print(obj.errors)
        return render(request, 'login.html', {'obj': obj})

login.html:

...
<form id="form" action="" method="POST" name="loginForm" novalidate>
	<!--{{ obj.as_p }}-->
    <div class="form-group">
        {{ obj.name.label }}
        <input type="text" class="form-control" name="name" placeholder="請輸入用戶名" value="{{ obj.cleaned_data.name }}">
        <div style="color: red;font-weight: bold">{{ obj.errors.name.0 }}</div>
    </div>
    <div class="form-group">
        {{ obj.pwd.label }}
        <input type="password" class="form-control" name="pwd" placeholder="請輸入密碼" value="{{ obj.cleaned_data.pwd }}">
        <div style="color: red;font-weight: bold">{{ obj.errors.pwd.0 }}</div>
    </div>
    <div class="form-group">
        {{ obj.email.label }}
        <input type="email" class="form-control" name="email" placeholder="請輸入郵箱" value="{{ obj.cleaned_data.email }}">
        <div style="color: red;font-weight: bold">{{ obj.errors.email.0 }}</div>
    </div>
    <div class="form-group">
        {{ obj.phone.label }}
        <input type="text" class="form-control" name="phone" placeholder="請輸入手機號" value="{{ obj.cleaned_data.phone }}">
        <div style="color: red;font-weight: bold">{{ obj.errors.phone.0 }}</div>
    </div>
    {% csrf_token %}
    <button id="loginBtn" type="submit" class="btn btn-primary">登錄</button>
</form>
...

上一次驗證通過的數據纔會被保存:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章