
## 表單
### HTML中的表單:
單純從前端的html來說,表單是用來提交數據給服務器的,不管后臺的服務器用的是Django還是PHP語言還是其他語言。只要把input標簽放在form標簽中,然后再添加一個提交按鈕,那么以后點擊提交按鈕,就可以將input標簽中對應的值提交給服務器了。
### Django中的表單
Django中的表單豐富了傳統的HTML語言中的表單。在Django中的表單,主要做以下兩件事
1. 渲染表單模板。
2. 表單驗證數據是否合法。
### Django中表單使用流程
在講解Django表單的具體每部分的細節之前。我們首先先來看下整體的使用流程。
首先我們在后臺服務器定義一個表單類,繼承自django.forms.Form
```
# forms.py
class MessageBoardForm(forms.Form):
title = forms.CharField(max_length=3,label='標題',min_length=2,error_messages={"min_length":'標題字符段不符合要求!'})
content = forms.CharField(widget=forms.Textarea,label='內容',error_messages={"required":'content字段必須填寫!'})
email = forms.EmailField(label='郵箱')
reply = forms.BooleanField(required=False,label='回復')
```
然后在視圖中,根據是GET還是POST請求來做相應的操作。如果是GET請求,那么返回一個空的表單,如果是POST請求,那么將提交上來的數據進行校驗。
```
from .forms import MessageForm
from django.views import View
from django.forms.utils import ErrorDict
class IndexView(View):
def get(self,request):
form = MessageBoardForm()
return render(request,'index.html',{'form':form})
def post(self,request):
form = MessageBoardForm(request.POST)
if form.is_valid():
title = form.cleaned_data.get('title')
content = form.cleaned_data.get('content')
email = form.cleaned_data.get('email')
reply = form.cleaned_data.get('reply')
return HttpResponse('success')
else:
print(form.errors)
return HttpResponse('fail')
```
在使用GET請求的時候,我們傳了一個form給模板,那么以后模板就可以使用form來生成一個表單的html代碼。在使用POST請求的時候,我們根據前端上傳上來的數據,構建一個新的表單,這個表單是用來驗證數據是否合法的,如果數據都驗證通過了,那么我們可以通過cleaned_data來獲取相應的數據。在模板中渲染表單的HTML
```
<form action="" method="post">
<table>
{{ form.as_table }}
<tr>
<td></td>
<td><input type="submit" value="提交"></td>
</tr>
</table>
</form>
```
我們在最外面給了一個form標簽,然后在里面使用了table標簽來進行美化,在使用form對象渲染的時候,使用的是table的方式,當然還可以使用ul的方式(as_ul),也可以使用p標簽的方式(as_p),并且在后面我們還加上了一個提交按鈕。這樣就可以生成一個表單了
### 常用的Field
使用Field可以是對數據驗證的第一步。你期望這個提交上來的數據是什么類型,那么就使用什么類型的Field。
### CharField
用來接收文本。
```
參數:
max_length:這個字段值的最大長度。
min_length:這個字段值的最小長度。
required:這個字段是否是必須的。默認是必須的。
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。
```
### 常用驗證器
在驗證某個字段的時候,可以傳遞一個validators參數用來指定驗證器,進一步對數據進行過濾。驗證器有很多,但是很多驗證器我們其實已經通過這個Field或者一些參數就可以指定了。比如EmailValidator,我們可以通過EmailField來指定,比如MaxValueValidator,我們可以通過max_value參數來指定。以下是一些常用的驗證器:
```
MaxValueValidator:驗證最大值。
MinValueValidator:驗證最小值。
MinLengthValidator:驗證最小長度。
MaxLengthValidator:驗證最大長度。
EmailValidator:驗證是否是郵箱格式。
URLValidator:驗證是否是URL格式。
RegexValidator:如果還需要更加復雜的驗證,那么我們可以通過正則表達式的驗證器:RegexValidator。比如現在要驗證手機號碼是否合格,那么我們可以通過以下代碼實現:
class MyForm(forms.Form):
telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='請輸入正確格式的手機號碼!')])
```
### 自定義驗證
有時候對一個字段驗證,不是一個長度,一個正則表達式能夠寫清楚的,還需要一些其他復雜的邏輯,那么我們可以對某個字段,進行自定義的驗證。比如在注冊的表單驗證中,我們想要驗證手機號碼是否已經被注冊過了,那么這時候就需要在數據庫中進行判斷才知道。對某個字段進行自定義的驗證方式是,定義一個方法,這個方法的名字定義規則是:clean_fieldname。如果驗證失敗,那么就拋出一個驗證錯誤。比如要驗證用戶表中手機號碼之前是否在數據庫中存在,那么可以通過以下代碼實現:
```
class MyForm(forms.Form):
telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='請輸入正確格式的手機號碼!')])
def clean_telephone(self):
telephone = self.cleaned_data.get('telephone')
exists = User.objects.filter(telephone=telephone).exists()
if exists:
raise forms.ValidationError("手機號碼已經存在!")
return telephone
```
以上是對某個字段進行驗證,如果驗證數據的時候,需要針對多個字段進行驗證,那么可以重寫clean方法。比如要在注冊的時候,要判斷提交的兩個密碼是否相等。那么可以使用以下代碼來完成:
```
class MyForm(forms.Form):
telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='請輸入正確格式的手機號碼!')])
pwd1 = forms.CharField(max_length=12)
pwd2 = forms.CharField(max_length=12)
def clean(self):
cleaned_data = super().clean()
pwd1 = cleaned_data.get('pwd1')
pwd2 = cleaned_data.get('pwd2')
if pwd1 != pwd2:
raise forms.ValidationError('兩個密碼不一致!')
```
### 提取錯誤信息
如果驗證失敗了,那么有一些錯誤信息是我們需要傳給前端的。這時候我們可以通過以下屬性來獲取:
```
1.form.errors:這個屬性獲取的錯誤信息是一個包含了html標簽的錯誤信息。
2.form.errors.get_json_data():這個方法獲取到的是一個字典類型的錯誤信息。將某個字段的名字作為key,錯誤信息作為值的一個字典。
3.form.as_json():這個方法是將form.get_json_data()返回的字典dump成json格式的字符串,方便進行傳輸。
4.上述方法獲取的字段的錯誤值,都是一個比較復雜的數據。比如以下:
{'username': [{'message': 'Enter a valid URL.', 'code': 'invalid'}, {'message': 'Ensure this value has at most 4 characters (it has 22).', 'code': 'max_length'}]}
```
那么如果我只想把錯誤信息放在一個列表中,而不要再放在一個字典中。這時候我們可以定義一個方法,把這個數據重新整理一份。
```
class MyForm(forms.Form):
username = forms.URLField(max_length=4)
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
```
這樣就可以把某個字段所有的錯誤信息直接放在這個列表中。
- 空白目錄
- 1-Django前導知識
- 1-1-虛擬環境
- 1-2-Django框架介紹與環境搭建
- 2-URL與視圖
- 2-1-URL與視圖
- 3-模板
- 3-1-模板介紹
- 3-2-模板變量
- 3-3-常用標簽
- 3-4-模板常用過濾器
- 3-5-模板結構優化
- 3-6-加載靜態文件
- 4-數據庫
- 4-1-操作數據庫
- 4-2-圖書管理系統
- 4-3-ORM模型介紹
- 4-4-ORM模型的增刪改查
- 4-5-模型常用屬性
- 4-6-外鍵和表
- 4-7-查詢操作
- 4-8-QuerySet的方法
- 4-9-ORM模型練習
- 4-10-ORM模型遷移
- 5-視圖高級
- 1-Django限制請求method
- 2-頁面重定向
- 3-HttpRequest對象
- 4-HttpResponse對象
- 5-類視圖
- 6-錯誤處理
- 6-表單
- 1-用表單驗證數據
- 2-ModelForm
- 3-文件上傳
- 7-session和cookie
- 1-session和cookie
- 8-memcached
- 1-memcached
- 9-阿里云部署
- 阿里云部署