首頁 > 後端開發 > Python教學 > Python中使用django form表單驗證的方法

Python中使用django form表單驗證的方法

高洛峰
發布: 2017-03-30 17:20:43
原創
2140 人瀏覽過

一. django form表單驗證引入

有時我們需要使用get,post等方式在前台HTML頁面提交一些資料到後台處理例;

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Form</title>
</head>
<body>
  <p>
    <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>
  </p>
</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={&#39;required&#39;: "邮箱不能为空"})
  password = forms.CharField(max_length=120,
                min_length=6,
                required=True,
                error_messages={&#39;required&#39;: "密码不能为空"})
  invite_code = forms.CharField(required=True,error_messages={&#39;required&#39;: "验证码不能为空"})
登入後複製

前端頁面

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>register</title>
</head>
<body>
  <p>
    <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>
  </p>
</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(userexact=user,pwdexact=pwd)
      if code.upper() == res_code.upper() and result:
        models.UserInfo.objects.filter(userexact=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),如果只想在views中查看所有報錯資訊print(f.errors),如果只想看用戶的可以

 print(form.errors[&#39;username&#39;][0])
登入後複製

錯誤訊息我們可以透過模板渲染回前端頁面,例

<form action="/form/" method="POST">
{% csrf_token %}
    <p class="input-group">
      {#接收后台传过来的form对象,自动生成input标签#}
      {{ form.user }}
      {#从后台传过来的error是字典,直接{{ error.user.0 }}呈现错误信息#}
       {#如果后台返回了错误信息,将错误信息放入span标签,在页面显示,否则不显示#}
      {% if error.username.0 %}
      <span>{{ error.userusername.0 }}</span>
      {% endif %}
    </p>
    <p class="input-group">
      {{ form.password }}
      {% if error.pwd.0 %}
      <span>{{ error.password .0 }}</span>
      {% endif %}
    </p>
    <p>
      <input type="submit" value="提交" />
    </p>
  </form>
登入後複製

三.自生成input框

Form類

class RegisterForm(forms.Form):
  style = &#39;form-control input-lg&#39;
  phone = forms.CharField(widget=forms.TextInput(attrs={&#39;class&#39;: style,
                              &#39;name&#39;: &#39;title&#39;})),
              required=True,
              error_messages={&#39;required&#39;: ugettext_lazy(&#39;*Required&#39;)})
  code = forms.CharField(widget=forms.NumberInput(attrs={&#39;placeholder&#39;: &#39;验证码&#39;,
                              &#39;class&#39;: style}),
              min_length=4,
              max_length=4,
              required=True,
              error_messages={&#39;required&#39;: ugettext_lazy(&#39;*Required&#39;)})
  password = forms.CharField(widget=forms.PasswordInput(attrs={&#39;placeholder&#39;: &#39;请输入密码&#39;,
                                 &#39;class&#39;: style}),
                min_length=6,
                required=True,
                error_messages={&#39;required&#39;: ugettext_lazy(&#39;*Required&#39;)})
登入後複製

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(userexact=user,pwdexact=pwd)
      if code.upper() == res_code.upper() and result:
        models.UserInfo.objects.filter(userexact=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})
登入後複製

Form類

<body>
  <form action="/form/" method="POST">
  {% csrf_token %}
    <p class="input-group">
{#      接收后台传过来的form对象,自动生成input标签#}
      {{ form.user }}
{#      从后台传过来的error是字典,直接{{ error.user.0 }}呈现错误信息#}
{#      如果后台返回了错误信息,将错误信息放入span标签,在页面显示,否则不显示#}
    <p class="input-group">
      {{ form.email }}
      {% if error.email.0 %}
      <span>{{ error.email.0 }}</span>
      {% endif %}
    </p>
     <p class="input-group">
      {{ form.password }}
      {% if error.password.0 %}
      <span>{{ error.password.0 }}</span>
      {% endif %}
    </p>
       <p class="input-group">
      {{ form.code }}
      {% if error.book_type.0 %}
      <span>{{ error.code.0 }}</span>
      {% endif %}
    </p>
    <p>
      <input type="submit" value="提交" />
    </p>
  </form>
</body>
</html>
登入後複製
完善

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 = 初始化值CharField(initial=value)

③重寫Form類別的init()方法:self.fields['onefield'].initial = value

④當給form傳參在stanse(即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={&#39;required&#39;: "邮箱不能为空"})
  password = forms.CharField(max_length=120,
                min_length=6,
                required=True,
                error_messages={&#39;required&#39;: "密码不能为空"})
  invite_code = forms.CharField(required=True,error_messages={&#39;required&#39;: "验证码不能为空"})
  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
登入後複製
以上所述是小編給大家介紹的Python中使用django form表單驗證的方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對PHP中文網的支持!

更多Python中使用django form表單驗證的方法相關文章請關注PHP中文網!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板