django form表單驗證


一. django form表單驗證引入  

有時時候我們需要使用get,post,put等方式在前台HTML頁面提交一些數據到后台處理例 ;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Form</title>
</head>
<body>
    <div>
        <form action="url"  method="post" enctype="multipart/form-data">{% csrf_token %}
            <input type="text" name="username"/>
            <input type="password" name="password"/>
            <input type="submit" value="submit"/>
        </form>
    </div>

</body>

前端提交后台獲取:

from django.shortcuts import render,HttpResponse,redirect
from app01 import models

def Login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        return HttpResponse("Hello,%s"%(username))

這樣就完成了基本的功能,基本上可以用了。

但是,如果用戶輸入並未按照要求(比如手機號要輸數據11位長度,密碼的復雜度等),還有就是提交后再回來已經輸入的數據也會沒了

當然如果我們手動將輸入之后的數據在 views 中都獲取到再傳遞到網頁,這樣是可行的,但是很不方便,所以 Django 提供了更簡單易用的 forms 來解決驗證等這一系列的問題

,在這里不得不提Django的插件庫真的很強大,簡單易擴展,上面的內容只是引進為什么要使用form,下面着重記錄django form的使用

二.form表單驗證應用

  需要在django的APP中新建一個模塊form.py,具體內容如下 

class RegisterForm(forms.Form):
    email = forms.EmailField(required=True,
                             error_messages={'required': "郵箱不能為空"})
    password = forms.CharField(max_length=120,
                               min_length=6,
                               required=True,
                               error_messages={'required':  "密碼不能為空"})
    invite_code = forms.CharField(required=True,error_messages={'required':  "驗證碼不能為空"})

前端頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>register</title>
</head>
<body>
    <div>
        <form action="url"  method="post" enctype="multipart/form-data">
            <input type="text" name="username"/>
            <input type="password" name="password"/>
           <input type="text" name="code"/>
            <input type="submit" value="submit"/>
        </form>
    </div>

</body>

后台views處理

def register(request):
    if request.method == "POST":
        f = Reg_Form(request.POST)
        if f.is_valid():
            user = f.cleaned_data["username"]
            pwd = f.cleaned_data["password"]
            code = f.cleaned_data["code"]
            res_code = request.session.get("code", None)
            result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd)
            if code.upper() == res_code.upper() and result:
                models.UserInfo.objects.filter(user__exact=user).update(status=1)
                request.session["user"] = user
                return redirect("/home")
            else:
                return render(request, "register.html", {"error": f.errors, "form": f})
  else:
    return render(request, "register.html")
Reg_Form(request.POST) 使用form類來處理提交的數據來驗證數據的合法性,is_valid()合法后的邏輯處理,驗證后的數據保存在實例化后返回的cleaned_data中,
cleaned_data是個字典的數據格式,錯誤信息保存在form.errors中比如說想在views中查看所有報錯信息print(f.errors),如果只想看用戶的可以
print(form.errors['username'][0])

錯誤信息我們可以通過 模板渲染回前端頁面,例
<form action="/form/" method="POST">
{% csrf_token %} <div class="input-group"> {#接收后台傳過來的form對象,自動生成input標簽#} {{ form.user }} {#從后台傳過來的error是字典,直接{{ error.user.0 }}呈現錯誤信息#}        {#如果后台返回了錯誤信息,將錯誤信息放入span標簽,在頁面顯示,否則不顯示#} {% if error.username.0 %} <span>{{ error.userusername.0 }}</span> {% endif %} </div> <div class="input-group"> {{ form.password }} {% if error.pwd.0 %} <span>{{ error.password .0 }}</span> {% endif %} </div> <div> <input type="submit" value="提交" /> </div> </form>

三.自生成input框

Form類

class RegisterForm(forms.Form):
    style = 'form-control input-lg'
    phone = forms.CharField(widget=forms.TextInput(attrs={'class': style,
                                                           'name': 'title'})),
                            required=True,
                            error_messages={'required': ugettext_lazy('*Required')})
    code = forms.CharField(widget=forms.NumberInput(attrs={'placeholder': '驗證碼',
                                                           'class': style}),
                           min_length=4,
                           max_length=4,
                           required=True,
                           error_messages={'required': ugettext_lazy('*Required')})
    password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': '請輸入密碼',
                                                                  'class': style}),
                                min_length=6,
                                required=True,
                                error_messages={'required': ugettext_lazy('*Required')})

views

def register(request):
    if request.method == "POST":
        f = RegisterForm(request.POST)
        if f.is_valid():
            user = f.cleaned_data["username"]
            pwd = f.cleaned_data["password"]
            code = f.cleaned_data["code"]
            res_code = request.session.get("CheckCode", None)
            result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd)
            if code.upper() == res_code.upper() and result:
                models.UserInfo.objects.filter(user__exact=user).update(status=1)
                request.session["user"] = user
                return redirect("/home")
            else:
                return render(request, "login.html", {"error": f.errors, "form": f})
        else:
            return render(request, "login.html", {"error": f.errors, "form": f})
    else:
    # 如果不是post提交數據,就不傳參數創建對象,並將對象返回給前台,直接生成input標簽,內容為空
        f = Log_Form()
        return render(request, "login.html", {"form": f})

前端頁面

<body>
    <form action="/form/" method="POST">
  {% csrf_token %}
<div class="input-group"> {# 接收后台傳過來的form對象,自動生成input標簽#} {{ form.user }} {# 從后台傳過來的error是字典,直接{{ error.user.0 }}呈現錯誤信息#} {# 如果后台返回了錯誤信息,將錯誤信息放入span標簽,在頁面顯示,否則不顯示#} <div class="input-group"> {{ form.email }} {% if error.email.0 %} <span>{{ error.email.0 }}</span> {% endif %} </div> <div class="input-group"> {{ form.password }} {% if error.password.0 %} <span>{{ error.password.0 }}</span> {% endif %} </div> <div class="input-group"> {{ form.code }} {% if error.book_type.0 %} <span>{{ error.code.0 }}</span> {% endif %} </div> <div> <input type="submit" value="提交" /> </div> </form> </body> </html>

四.Form驗證完善

https://docs.djangoproject.com/en/dev/ref/forms/validation/

  • form驗證的運行順序是init,clean,validte,save

其中clean和validate會在form.is_valid()方法中被先后調用

clean等步驟遇到的異常:Exception Value: argument of type 'NoneType' is not iterable.
可能是cleaned_data中某個字段值應該是個列表,實際上卻是空值。

clean方法重寫時一定不要忘了return cleaned_data

這樣重寫可以使用戶提交的數據在form類中執行檢測完后返回數據給用戶,數據合法后進行邏輯處理,不需要再進行處理返回用戶,更方便更合理

補充:
5.form的四種初始化方式
①實例化oneform(initial={'onefield':value})
②定義字段時給初始化值oneformfield = forms.CharField(initial=value)
③重寫Form類的__init__()方法:self.fields['onefield'].initial = value
④當給form傳參instanse(即oneform(instanse=onemodel_instance))時,前三種初始化方法會全部失效,即使重寫__init__時,先調用父類的__init__再使用方法③,仍然無效(不是很爽)。
這時想重新初始化字段值只能在__init__()里 self.initial['title'] = value,直接對Form類的initial屬性字典賦值。

from django import forms

class RegisterForm(forms.Form):
    email = forms.EmailField(required=True,
                             error_messages={'required': "郵箱不能為空"})
    password = forms.CharField(max_length=120,
                               min_length=6,
                               required=True,
                               error_messages={'required':  "密碼不能為空"})
    invite_code = forms.CharField(required=True,error_messages={'required':  "驗證碼不能為空"})

    def clean(self):
        # 用戶名
        try:
            email = self.cleaned_data['email']
        except Exception as e:
            raise forms.ValidationError(u"注冊賬號需為郵箱格式")
        # 驗證郵箱
        user = User.objects.filter(username=email)
        if user:  # 郵箱已經被注冊了
            raise forms.ValidationError(u"郵箱已被注冊")
        # 密碼
        try:
            password = self.cleaned_data['password']
        except Exception as e:
            print('except: ' + str(e))
            raise forms.ValidationError(u"請輸入至少6位密碼")


        return self.cleaned_data

 


免責聲明!

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



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