您好,登錄后才能下訂單哦!
最近在項目上用到了 Django 的自帶的 Form 表單,遇到了一些坑,今天給大家出的這篇 Python基礎教程 也是做了一個簡單的總結,大家可以對號出坑。
Form 基礎介紹
首先讓我們先來了解下 Django 中 Form 表單的基本用法。Django 中提供了兩種 Form 表單類型,一種是 forms.Form ,另外一種是 forms.ModelForm 。很明顯,一種是普通的 Form 表單類型,另外一種是和 Model 有關聯的表單類型。官方文檔中是這樣來介紹 ModelForm 的:
If you’re building a database-driven app, chances are you’ll have forms that map closely to Django models. For instance, you might have a BlogComment model, and you want to create a form that lets people submit comments. In this case, it would be redundant to define the field types in your form, because you’ve already defined the fields in your model.
For this reason, Django provides a helper class that lets you create a Form class from a Django model.
對于 Django 中的 Form 表單的用法,我們只需要了解以下幾點:
問題總結
在這次項目需求中,我主要遇到的問題是,有幾個表單頁面,后臺使用同一張表去做存儲,但是每個頁面有許多變化的元素,如果為了存儲這些可變的值,每個元素都用數據庫一個字段去做存儲不太現實,因為需求是一直在變化的。所以我采用的解決辦法是提取公共的元素,其他可變的元素用了一個json字段存在數據庫中。
而這樣導致的問題就是,不能使用 ModelForm ,我選擇了使用普通的 forms.Form 。這樣遇到了一些問題,總結如下:
1 . forms.Form 的初始化
有兩種初始化方式:
# 第一種方式: # 初始化一個空的 form 表單,同時綁定頁面上的表單輸入值,即能接受頁面上的輸入值 # 能接受頁面上的輸入值,這點很重要 form = UserForm(request.POST or None, request.FILES or None) # 第二種方式: # 接受一個字典,做賦值初始化 form = UserForm({'name': 'Demon', 'age': 8})
基于這兩種做法,我很顯然的在 view.py 中寫出了這樣的代碼:
def create_user(request): # 根據是否傳入 uid 來判斷是創建還是編輯 uid = request.GET.get('uid', '') if uid: # 如果傳入了 uid ,查找當前 uid account = Account.objects.filter(id=uid).first() # 封裝當前 賬號 的信息,做表單初始化 # 為了說明問題,不考慮 account 沒有找到的情況 user_info = { 'name': account.name, 'age': account.age } # 表單初始化 form = UserForm(user_info) else: # 如果是新建,則初始化一個空的表單 form = UserForm(request.POST or None, request.FILES or None) if request.method == 'POST': if form.is_valid(): # do save opertion pass return render(request, 'xxx/xxx.html', local())
看上去一切安好,代碼也十分簡單。但問題來了,新建還行,但當我們使用編輯的時候,會發現,沒辦法做修改,即當代碼走到 form.is_valid() 時,它始終做了 dict 的初始化,它不再會接受你新輸入的值。
解決思路如下:
每次都初始化一個空的 form ,前端渲染頁面時,用 js 去控制頁面的展示。這也比較簡單,這里不做多的說明。
2 . 圖片格式編輯頁如何獲取之前展示的結果
對于圖片,新建的時候上傳還比較簡單,問題是在于如果是編輯,如何帶回原來的上傳結果。我們都知道 是沒辦法賦值的。所以表單初始化的時候,也沒有辦法進行賦值。
解決思路如下:
在表單中新開一個字段,用來存儲上傳后的圖片鏈接,當圖片未上傳時,整個 div 隱藏,當圖片有值時,整個 div 展示。后端通過判斷真正的 file 字段 與 url 字段,來判斷是否有新上傳文件
3 . clean_xxx 方法未返回值時,form.clean_data[‘xxx’] 獲取不到值
這是需要比較注意的一點,我們可以通過寫 clean_xxx(self) 的方法,來對表單的某個屬性做校驗,但一旦校驗通過,注意一定要返回當前輸入的值。正確示例如下:
class UserForm(forms.Form): """用戶表單""" name = forms.IntegerField(label='姓名', required=True) age = forms.IntegerField(label='年齡', required=True, min_value=0) def clean_name(self): """name不超過20個字符""" name = self.cleaned_data.get('name') if not name: raise forms.ValidationError('請輸入姓名') if name and len(name) > 20: raise forms.ValidationError('長度不超過20') # 注意一定要返回輸入值,否則后端獲取不到輸入的值 return account_id
小結
form.Forms 我還算是比較經常用的,我覺得封裝了很多比較好的用法,比如限制必輸,限制最小值、最大值等。只要避免一些坑,就會比較得心應手了。希望這次總結的坑,你沒有入!也歡迎大家的補充!更多的 Python基礎教程 也會繼續為大家更新!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。