Django之Form表單

1:什麼是表單html

2:HTML表單與Django表單數據庫

3:Django中表單的使用流程django

4:經常使用的字段與驗證器json

5:自定義驗證器app

6:  提取錯誤信息
post

7:ModelForm:網站

  (1)自定義錯誤消息ui

  (2)save()方法url

 

1什麼是表單:表單是用來收集用戶信息的表的集合,好比用戶在網站上登入(輸入本身的用戶名,密碼提交到網站)這個過程用到的表就是表單spa

2HTML表單與django表單
  html表單:form標籤,提交地址,請求方式,提交按鈕

<form action="" method="post" enctype="multipart/form-data">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="file">
    <input type="checkbox">
    <input type="submit">
</form>

  django表單:是由Form類實現的,主要分爲forms.Form和forms.ModelForm兩種,前者爲基本的表單或者爲結合模型生成的表單

  django表單的做用:(1)相似於html頁面同樣生成表單模板(2)對錶單提交上來的數據進行驗證(重點)

3:django表單使用的基本流程:

  (1)生成一個表單模板:

  在APP中建立一個py文件,名字爲forms;這裏面寫表單的內容:目錄以下

  forms.py代碼:

from django import forms

class IndexForm(forms.Form):
    title = forms.CharField(max_length=12,label="標題")  //max_length表示最大長度,label表示標題名字
    content = forms.CharField(widget= forms.Textarea,label="內容") //widget表示表單的屬性
    replay = forms.BooleanField(required=False,label="記住我")

  view.py代碼:

from django.shortcuts import render
from django.views.generic import View
from .forms import IndexForm
class IndexView(View):
    def get(self,request):    //get請求的時候,返回一個IndexForm
        form = IndexForm()
        return render(request,"index.html",context={"form":form})

  html代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post">
    <table>
        {{ form.as_table  }}    //在HTML中渲染一個表單三種方式(form.as_table,form.as_ul,form.as_p),以後還要添加提交按鈕
        <tr>
            <td></td>
            <td><input type="submit"></td>
        </tr>
    </table>
</form>
</body>
</html>

   (2)對錶單提交上來的數據進行驗證

  forms.py

from django import forms

class IndexFrom(forms.Form):
    title = forms.CharField(max_length=12,label="標題",min_length=4)  //最少不能小於4個
    content = forms.CharField(widget= forms.Textarea,label="內容")
    email = forms.EmailField()    //添加一個郵箱的驗證
    replay = forms.BooleanField(required=False,label="記住我")  //required=False  表示值能夠不填,默認爲True

  view.py

from django.shortcuts import render,HttpResponse
from django.views.generic import View
from .forms import IndexFrom
class IndexView(View):
    def get(self,request):
        form = IndexFrom()
        return render(request,"index.html",context={"form":form})

    def post(self,request):
        form = IndexFrom(request.POST)   //將request.POST接收到的值傳給IndexForm表單進行驗證,
        if form.is_valid():   //若是驗證成功則爲True
            return HttpResponse("ok")
        else:
            print(form.errors.get_json_data())
            return HttpResponse("fail")

4:經常使用的驗證器

  (1)經常使用的字段(Field):

    CharField:  用來接收文本

      max_length:表示最大長度

      min_length:表示最小長度

      required:表示是否必須填寫,默認爲True(必須)

      error_messages:驗證失敗給出的錯誤信息

    EmailField:用來驗證郵箱

      錯誤信息的key:required,invalid

    FloatField:用來接收浮點類型,經過驗證後會將值轉換爲浮點型

      max_value:最大值

      min_value:最小值

      錯誤信息的key:required,invalid,max_value,min_value

    IntegerField:用來接收整型,經過驗證後會將值轉換爲整型

      max_value:最大值

      min_value:最小值

      錯誤信息的key:required,invalid,max_value,min_value

   URLField:用來接收url格式的字符串

      錯誤信息的key:required,invalid

  (2)經常使用的驗證器(validator):在驗證某個字段的時候能夠傳遞一個驗證器對數據進一步驗證

    MaxValueValidator:驗證最大值

    MinValueValidator:驗證最小值

    MaxLengthValidator:驗證最大長度

    MinLengthValidator:驗證最小長度

    EmailValidator:驗證是不是郵箱格式

    URLValidator:驗證是不是URL格式

    RegexValidator:正則驗證

from django import forms
from django.core import validators  //導入驗證器
class IndexFrom(forms.Form):
    telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message="請輸入正確的手機號")])  //驗證手機號

  5自定義驗證器

  (1)若是要對一個字段進行驗證不是一個長度,也不是一個最大值,正則或者也表達不清楚,還須要一些更復雜的邏輯,那麼咱們能夠對這個字段進行自定義驗證;好比註冊的時候咱們要判斷數據庫中有沒有這個手機號,有的話就不能再註冊了,這是咱們就要在數據庫中判斷才知道,那麼就要定義一個方法;這個方法有一個規則就是clean_fieldname(好比:clean_telephone,clean_username等,是個是固定的),好比咱們要對手機號進行驗證:

from django import forms
from django.core import validators
from .models import User
class IndexFrom(forms.Form):
    title = forms.CharField(max_length=12,label="標題",min_length=4)
    content = forms.CharField(widget= forms.Textarea,label="內容")
    email = forms.EmailField()
    replay = forms.BooleanField(required=False,label="記住我")
    telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message="請輸入正確的手機號")])

    def clean_telephone(self):      //對手機號進行驗證方式(clean_telephone)
        telephone = self.cleaned_data.get("telephone")    //拿到這個手機號
        exists = User.objects.filter(telephone=telephone).exists()   //在數據庫中判斷是否存在
        if exists:
            raise forms.ValidationError("手機號已經存在")
        else:
            return telephone

  (2)以上是對單個字段進行驗證,若是是對多個字段進行驗證的話就能夠重寫clean方法; 好比註冊的時候要判斷兩次輸入的密碼是否一致:

from django import forms
from django.core import validators
from .models import User
class IndexFrom(forms.Form):
    title = forms.CharField(max_length=12,label="標題",min_length=4)
    content = forms.CharField(widget= forms.Textarea,label="內容")
    email = forms.EmailField()
    password = forms.CharField(max_length=18,min_length=6)
    re_password = forms.CharField(max_length=18,min_length=6)
    replay = forms.BooleanField(required=False,label="記住我")
    telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message="請輸入正確的手機號")])

    def clean(self):    //重寫clean方法
        cleaned_data = super().clean()   //調用父的clean()
        password = cleaned_data.get("password")
        re_password = cleaned_data.get("re_password")
        if password != re_password:
            raise forms.ValidationError("兩次密碼不一致")
        return cleaned_data

  6提取錯誤信息

  若是驗證失敗了,會有一些錯誤提示信息,如:

  form.errors:這個屬性的錯誤信息是包含了一些html標籤的錯誤信息

  form.errors.get_json_data():這個方法獲取到的是一個字典類型的錯誤信息,將某個字段的名字做爲key,錯誤信息爲值得字典

  form.as_json():這個方法是將form.get_json_data()返回的字典dump成json格式的字符串。

  以上方法獲取的都是比較複雜的數據好比:
  

{'email': [{'message': 'Enter a valid email address.', 'code': 'invalid'}], '__all__': [{'message': '兩次密碼不一致', 'code': ''}]}

  若是咱們想把錯誤信息放到一個列表而不是字典中,咱們能夠本身定義一個方法,對錯誤信息從新整理:

    def get_errors(self):
        errors = self.errors.get_json_data()
        new_errors = {}
        for key,message_dicts in errors.items():   //對字典進行遍歷
            messages = []
            for message in message_dicts:   //
                messages.append(message["message"])
            new_errors[key] = messages
        return new_errors

  7ModelForm:

  (1)咱們在寫表單的時候發現表單中的Field和模型中的Field基本上同樣,並且表單中須要驗證的數據就是咱們要保存到數據庫中的數據,那麼咱們就能夠將二者綁定。好比咱們有個模型(User):

from django.db import models

class User(models.Model):
    username = models.CharField(max_length=12)
    telephone = models.CharField(max_length=11)
    password = models.CharField(max_length=18)
    email = models.EmailField()

    class Meta:
        db_table = "user"

  那麼咱們再寫表單的時候能夠這樣寫:

class UserForm(forms.ModelForm):   //繼承自ModelForm
    class Meta:    //定義Meta類
        model = User   //規定繼承自那個模型
        fields = "__all__"  //規定繼承那些字段(繼承全部字段)
        # fields = ["username","telephone"]    //繼承username,telephone兩個字段
        # exclude = ["username"]  //除了username字段其餘都繼承
        error_messages={           //定義一個錯誤提示信息
            "username":{"max_length":"最多不能超過10個字符","min_length":"最少不能少於3個字符"},
            "telephone":{"required":"必須傳入手機號"}
        }

  (2)save()方法:這個方法是把數據直接保存到數據庫中(必須保證clean方法沒有問題以後才能使用,否則會報錯),咱們還能夠傳入一個參數commit=False;表示只會生成一個對象不會真正的保存到數據庫中。

 def post(self,request):
        form = IndexFrom(request.POST)
        if form.is_valid():
            # form.save()      //直接保存到數據庫中
            user = form.save(commit=False)  //生成一個user對象
            user.password = "123123"  //給對象添加一個密碼
            user.save()  //保存到數據庫中
            
            return HttpResponse("ok")
相關文章
相關標籤/搜索