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")