Django中的Form表單驗證


回憶一下Form表單驗證的邏輯:

前端有若干個input輸入框,將用戶輸入內容,以字典傳遞給后端。

后端預先存在一個Form表單驗證的基類,封裝了一個檢測用戶輸入是否全部通過的方法。該方法會先定義好錯誤信息的字典,並會遍歷類的所有屬性(對應前端待驗證的輸入域),調用各自的驗證方法,將錯誤信息(兩類,必要與否以及格式正確與否)存入字典,並得出最終的驗證結果。在使用時,需要定義繼承自Form基類不同的Form類,以對應有着不同輸入域的Form表單。在拿到前端給的字典前,要先初始化自定義From類,直接執行封裝好的整體驗證方法,拿到結果后就可以拋給前端了。

Django中Form表單驗證涉及到的知識:

1.Django中的ErrorDcit類如何封裝了錯誤信息

# project/app01/forms.py

from django import forms

# 繼承自Django的Form類
# 內部以字段形式定義驗證域
class MyForm(forms.Form):
    user = forms.CharField()
    pwd = forms.CharField()
# project/app01/views.py
def form(request):
    from app01.forms import MyForm
    if request.method == 'POST':
        f = MyForm(request.POST)
        ret = f.is_valid()  # bool
        data = f.cleaned_data  # {'user': 'asd', 'pwd': 'asd'}
        errors = f.errors  # ErrorDict,打印時因為__str__方法,會顯示位ul標簽的形式
        print(errors.get('user', None)[0] if errors.get('user', None) else None)  # ErrorList,以索引取出第一條錯誤信息
        return render(request, "form.html", {"errors": f.errors})
    return render(request, "form.html")
# project/templates/forms.html        
<form action="/form/" method="post">
    <div>
        用戶名:<input type="text" name="user"/>
    </div>
    <div>
        密碼:<input type="password" name="pwd"/>
    </div>
    <div>
        <input type="submit" value="提交"/>
    </div>
    {{ errors }}
    <div></div>

 

2.拋給前端的ErrorDcit及使用模板語言漂合理展示

   展示錯誤信息的前端布局

   通過返回Form類和模板語言在前端動態生成input標簽

# project/app01/views.py
def form(request):
    from app01.forms import MyForm
    empty_form = MyForm()
    if request.method == 'POST':
        f = MyForm(request.POST)
        if f.is_valid():
            print(f.cleaned_data)
            # 這里只是為了使得正確提交后不至於讓input消失,實際壞境中這里應該是用戶信息驗證 
            return render(request, "form.html", {'myform': empty_form})
        return render(request, "form.html", {"errors": f.errors, "myform": f})
    else:
        return render(request, "form.html", {'myform': empty_form})
# project/templates/forms.html    
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .input-group{
        padding: 15px;
    }
    .input-group input{
        width: 200px;
    }
    .input-group span{
        display: inline-block;
        position: relative;
        border: 1px solid red;
        top: 25px;
        left: -211px;
    }

    </style>
</head>
<body>
    <form action="/form/" method="post">
        <div class="input-group">
            <div style="float:left;width:70px;">用戶名:</div>
            {{ myform.user }}
            {% if errors.user.0 %}
            <span>{{ errors.user.0 }}</span>
            {% endif %}
        </div>
        <div class="input-group">
            <div style="float:left;width:70px;">密碼:</div>
            {{ myform.pwd }}
            {% if errors.pwd.0 %}
            <span>{{ errors.pwd.0 }}</span>
            {% endif %}
        </div>
        <div>
            <input style="float:left;margin-left:15px;" type="submit" value="提交"/>
        </div>
    </form>

4.django.forms中的CharField參數

(required, min/max_length,error_messages,forms.widget)

   不重啟服務時數據庫數據動態更新到前端(靜態字段的特點)

   field不合需求時自定義驗證規則(validators參數)

   

# project/app01/forms.py
    
from django import forms
from app01 import models


def mobile_validate(value):
    import re
    mobile_re = re.compile("^(13[0-9]|14[579]|15[0-3,5-9]|1 6[6]|17[0135678]|18[0-9]|19[89])\\d{8}$")
    if not mobile_re.match(value):
        print('123123')
        raise forms.ValidationError('手機號碼格式不對哦')


class MyForm(forms.Form):

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['book_type'] = forms.CharField(
            widget=forms.Select(choices=models.BookType.objects.values_list('id', 'caption'))
        )

    user = forms.CharField(min_length=4, max_length=10, widget=forms.TextInput)
    pwd = forms.CharField(error_messages={'required': '為什么不輸入密碼??'})
    email = forms.EmailField(error_messages={'required': '郵箱還沒輸入哦', 'invalid': '郵箱格式錯誤'})
    # book_type_choices = (
    #     (0, '小說'),  value
    #     (1, '科普'),  innerText
    # )  # 元組內有元組
    # 從數據庫獲得數據

    # 注意這里filed都是靜態字段
    # 類的靜態字段只創建一次以后不會再修改,新的對象都會使用同一份數據
    # 所以MyForm這里的靜態字段只會執行一次
    # 加入數據庫中的數據更新了,服務器不重啟的話,這里從數據庫取來的值是不會變的
    # 因此將該字段寫入類的初始化方法里,不要忘了執行父類的初始化方法哦
    # book_type_choices = models.BookType.objects.values_list('id', 'caption')
    # book_type = forms.CharField(
    #     widget=forms.Select(choices=book_type_choices)
    # )
    comment = forms.CharField(
        widget=forms.Textarea(attrs={'style': 'border:1px solid red;'})
    )  # 可以為生成的標簽添加屬性

    mobile = forms.CharField(
        validators=[mobile_validate, ],
        error_messages={'required': '手機號不填不行'},
        widget=forms.TextInput
    )
<div class="input-group">
            <div style="float:left;width:70px;">用戶名:</div>
            {{ myform.user }}
            {% if errors.user.0 %}
            <span>{{ errors.user.0 }}</span>
            {% endif %}
        </div>
        <div class="input-group">
            <div style="float:left;width:70px;">密碼:</div>
            {{ myform.pwd }}
            {% if errors.pwd.0 %}
            <span>{{ errors.pwd.0 }}</span>
            {% endif %}
        </div>
        <div class="input-group">
            <div style="float:left;width:70px;">郵箱:</div>
            {{ myform.email }}
            {% if errors.email.0 %}
            <span>{{ errors.email.0 }}</span>
            {% endif %}
// 以下都是上面input-group標簽的重復,只是field不同而已,不再細說

 碎碎念:

中間給render傳入兩個字典,一直調試不出問題,費時頗久,下次留心。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM