對于請求中提交的表單資料,Django中可以使用類的方式進行處理,就像資料庫中的表對應于Django中的一個ORM模型類,表單也是對應于一個Form類,Form類主要用于表單資料的驗證功能,使得我們在驗證表單中的資料時變得非常方便快捷,當然,不使用Form類也是可以處理表單資料的,只是大多數情況下使用Form類會方便很多,也是看個人的使用習慣和作業需要了,
一、Form類
Form類在from django import forms中,使用時需要定義一個Form的子類,相當于將請求的表單資料封裝到一個特殊的類中,并自動完成一些資料的驗證作業,
1、Form基本使用
Form子類中的屬性名對應于HTML標簽中的name屬性值,可以根據表單中的資料型別在類中定義相應的屬性欄位,
- 每一種欄位都有其基本的驗證器,如
forms.EmailField會自動驗證接收的資料是否為郵箱格式, - 可以使用
is_valid()方法判斷是否所有的欄位都已通過驗證, - 如果沒有通過驗證,可以通過表單中的
errors物件查看錯誤資訊,如errors.get_json_data()是以字典的形式輸出驗證失敗提示資訊,
示例:在app下新建一個forms.py用于存放所有的表單類
"""forms.py"""
from django import forms
class MessageBoardForm(forms.Form):
"""新建一個Form子類,用于接收表單中的4個值:title,content,email,reply"""
# 接收文本型別資料,error_messages引數用于指定資料不滿足相應條件時的錯誤提示資訊
title = forms.CharField(max_length=100, min_length=2, error_messages={'max_length': '最多只能有100個字符!'})
# 接收文本型別資料,widget引數用于指定控制元件型別,forms.Textarea表示多行文本框控制元件
content = forms.CharField(widget=forms.Textarea)
# 接收郵箱格式資料
email = forms.EmailField(error_messages={'required': '必須輸入郵箱!'})
# 接收布爾型別資料,required引數表示此欄位是否為必須的,默認為True,False表示可以不傳此引數,即沒有接收到此欄位也是允許的
reply = forms.BooleanField(required=False)
"""views.py"""
from django.views.generic import View
from django.http import HttpResponse
from .forms import MessageBoardForm
# 定義一個視圖類
class IndexView(View):
# 處理post請求
def post(self, request):
# 將表單資料傳入Form子類中,如果表單資料有多種型別時,
# 可以直接傳入,如form = MessageBoardForm(request.POST, request.FILES)
form = MessageBoardForm(request.POST)
# 判斷所有欄位是否都通過驗證
if form.is_valid():
# 通過驗證后,所有欄位的資料都存放在cleaned_data中
title = form.cleaned_data.get('title')
content = form.cleaned_data.get('content')
email = form.cleaned_data.get('email')
reply = form.cleaned_data.get('reply')
print(title)
print(content)
print(email)
print(reply)
return HttpResponse('success!')
else:
# get_json_data方法以字典的形式輸出沒有通過驗證的錯誤資訊
print(form.errors.get_json_data())
return HttpResponse('fail!')
2、常用Field欄位
常用的Field欄位和引數使用如下:
CharField:接收文本資料,常用的引數:max_length:文本的最大長度,min_length:文本的最小長度,required:欄位是否必須指定,默認是True,error_messages:欄位驗證失敗時給出的錯誤提示資訊,需要傳入一個字典,字典中需要指定對應驗證條件的錯誤提示資訊,如error_messages={'max_length': '最多只能有100個字符!'}表示指定文本最大長度不滿足時給出提示資訊,
EmailField:接收文本資訊,并驗證是否為郵箱格式,常用的錯誤提示型別有:required、invalid,FloatField:接收浮點型別資料,并且驗證通過后會將這個欄位轉換為浮點型別,常用的引數:max_value:最大值,min_value:最小值,- 常用的錯誤提示型別有:
required、invalid、max_value、min_value,
IntegerField:接收整型資料,并且驗證通過后會將這個欄位轉換為整型,常用的引數:max_value:最大值,min_value:最小值,- 常用的錯誤提示型別有:
required、invalid、max_value、min_value,
URLField:接收url格式字串,常用的錯誤提示型別有:required、invalid,
3、驗證器
Form類中的各個Field欄位其實都有一些基本的驗證器,如果表單中的某個欄位想要額外添加一些驗證功能,可以指定validators引數給欄位添加一些驗證器,或者給這個欄位定義一個額外的形如clean_[欄位名]自定義驗證方法,
內置驗證器:內置驗證器通過欄位的validators引數指定對應的驗證器串列即可,Django內置的驗證器都在django.core.validators中,常用的內置驗證器:
MaxValueValidator:最大值,MinValueValidator:最小值,MaxLengthValidator:最大長度,MinLengthValidator:最小長度,EmailValidator:是否為郵箱格式,URLValidator:是否為url格式,RegexValidator:是否符合正則運算式,使用時傳入一個正則運算式即可,FileExtensionValidator:驗證檔案名后綴是否符合要求,使用時傳入一個檔案名后綴的串列,如['txt', 'csv'],表示只允許上傳這些型別的檔案,
自定義驗證:需要針對某個欄位進行特殊驗證時,可以在Form表單類中定義一個clean_[欄位名]的方法,就會自動執行這個方法進行驗證了,如果不符合要求,直接拋出例外即可,符合要求則回傳對應的值,如果想要針對多個欄位之間的驗證,可以重寫clean()方法,當所有欄位的驗證都通過后就會執行這個方法,
"""forms.py"""
from django import forms
from django.core import validators
from .models import User
class RegisterForm(forms.Form):
"""定義一個注冊功能的Form子類,用來接收注冊的相關資訊"""
username = forms.CharField(max_length=100)
# 添加一個正則運算式的驗證器,message引數表示驗證失敗時的錯誤提示資訊
telephone = forms.CharField(validators=[validators.RegexValidator(r'1[345678]\d{9}', message='請輸入正確格式的手機號碼!')])
pwd1 = forms.CharField(max_length=16, min_length=6)
pwd2 = forms.CharField(max_length=16, min_length=6)
def clean_telephone(self):
# 當欄位的基本驗證通過后,會將資料存盤在cleaned_data中
telephone = self.cleaned_data.get('telephone')
# 在資料庫中查找是否有相同的手機號,User為用戶的ORM模型類
exists = User.objects.filter(telephone=telephone).exists()
if exists:
raise forms.ValidationError(message='{}已經被注冊!'.format(telephone))
# 需要回傳處理后的值
return telephone
def clean(self):
# 執行這個方法時表示所有欄位都已驗證成功,當然,需要先呼叫父類的clean()方法
cleaned_data = https://www.cnblogs.com/guyuyun/archive/2020/10/18/super().clean()
pwd1 = cleaned_data.get('pwd1')
pwd2 = cleaned_data.get('pwd2')
if pwd1 != pwd2:
raise forms.ValidationError(message='兩次輸入的密碼不一致!')
# 回傳處理后的資料
return cleaned_data
二、ModelForm類
如果表單提交的資訊與已有的ORM模型是一致的,比如提交的資訊會直接存盤到資料庫中,而資料庫中對應表在代碼中已有相應的ORM模型類了,那么就可以使用ModelForm類,可以免去我們很多的重復作業,ModelForm類有許多用法都是和Form類是類似的,使用時可以參考下,
使用ModelForm比較簡單,需要定義一個ModelForm的子類,基本使用如下:
- 需要定義一個名為
Meta的內部類來關聯ORM模型類,Meta類的常用屬性如下:model:指定關聯的ORM模型類,fields:指定關聯的欄位,__all__表示全部欄位,也可以使用串列指定需要的欄位,exclude:指定排除的欄位,即除了此屬性指定的欄位,其他欄位都需要關聯,error_messages:指定驗證失敗時的錯誤提示資訊,
"""forms.py"""
from django import forms
from .models import Book
class MyForm(forms.ModelForm):
# 如果想要自定義驗證方式,也是和Form類一樣的定義方式
def clean_page(self):
page = self.cleaned_data.get('page')
if page > 1000:
raise forms.ValidationError('page不能大于1000!')
return page
class Meta:
# ORM模型類
model = Book
# 指定需要驗證的欄位,__all__表示所有欄位,也可以使用串列將需要的欄位放進去即可
fields = '__all__'
# fields = ['title', 'page']
# fields和exclude兩個屬性必須指定其中一個
# 表示除了這個欄位其他欄位都需要
# exclude = ['price']
# 指定驗證失敗時的錯誤提示資訊
error_messages = {
'title': {
'required': '請輸入標題!',
'invalid': '請輸入正確格式的標題!'
}
}
- 雖然可以關聯到ORM模型類,但是
ModelForm子類中也是可以定義自己的屬性欄位的,定義方式也是和Form子類的定義是一樣的,比如提交的表單資訊比ORM模型中的欄位多的時候就可以這樣做, - 驗證時,可以在ORM模型的欄位定義中指定
validators引數,添加額外的驗證器即可,如果要對某個欄位自定義驗證方式時,在ModelForm子類中像Form類一樣,定義一個clean_[欄位名]的方法來處理即可,
"""models.py"""
from django.db import models
from django.core import validators
class Book(models.Model):
title = models.CharField(max_length=100)
page = models.IntegerField()
# 可以直接在ORM模型欄位中添加驗證器
price = models.FloatField(validators=[validators.MaxValueValidator(limit_value=https://www.cnblogs.com/guyuyun/archive/2020/10/18/250)])
- 當表單的驗證都通過之后,可以呼叫
save()方法將資料直接保存到資料庫中,如果不想直接提交到資料庫中,或者還需要給ORM模型中的某些欄位指定值,可以使用如user = user_form.save(commit=False),指定commit引數為False之后,就只是生成對應的模型物件并回傳,并不會映射到資料庫中,修改完成后,再呼叫模型物件的save()方法即可,
"""views.py"""
from django.http import HttpResponse
from django.views.decorators.http import require_POST
from .forms import RegisterForm
# 定義一個視圖函式,只允許post的請求方式
@require_POST
def register(request):
# 將post的資料傳入ModelForm類中
user_form = RegisterForm(request.POST)
if user_form.is_valid():
# 只是同步ORM模型類,但并不映射到資料庫中
user = user_form.save(commit=False)
# 重新指定密碼
user.password = user_form.cleaned_data.get('password')
# 保存到資料庫中
user.save()
return HttpResponse('success!')
else:
return HttpResponse('fail!')
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/179276.html
標籤:其他
下一篇:數字加密
