表單只是簡化和加速(開發)從請求中獲取POST數據的過程的工具。手動的方式是爲所有的字段做一些HTML格式的request.POST.get('somefield')
。但是Django的可以做的比這更好的...
在本質上,一個Form類包含若干領域,並執行以下任務:
- 顯示HTML輸入,
- 收集和驗證數據時用戶提交它
- 如果字段不驗證,則返回值和錯誤消息爲HTML
- 如果所有字段都是有效的,請提供
form.cleaned_data
字典作爲訪問這些值的便捷方式。
使用這些值,我可以手動創建一個MyModel
的新實例並保存它。當然,我必須在MyModel模型中的每個字段的表單中定義一個字段。
這意味着,基本上,我可以做這樣的事情:
(原諒我沒有測試此代碼,所以我不能保證它的正確率100%)
models.py:
class MyModel(models.Model):
field1 = models.CharField(max_length=40, blank=False, null=False)
field2 = models.CharField(max_length=60, blank=True, null=True)
forms.py:
class FormForMyModel(forms.Form):
form_field1 = forms.CharField(max_length=40, required=True)
form_field2 = forms.CharField(max_length=60, required=False)
views.py:
def create_a_my_model(request):
if request.method == 'POST':
form = FormForMyModel(request.POST)
if form.is_valid():
my_model = MyModel()
my_model.field1 = form.cleaned_data.get('form_field1', 'default1')
my_model.field2 = form.cleaned_data.get('form_field2', 'default2')
my_model.save()
else:
form = FormForMyModel()
context_data = {'form': form}
return HttpResponse('templtate.html', context_data)
(這可以用少量代碼寫成,但它應該儘可能清晰)
注意模型字段和表單字段之間沒有關係!創建MyModel實例時,我們必須手動分配值。
上面的例子概述了通用表格工作流程。它經常在複雜情況下需要,但不是像這個例子那樣簡單。
對於這個例子(和現實世界的例子很多),Django的可以做的比這更好的...
您可以注意到在上面例如兩個惱人的問題:
- 我有分別在
MyModel
和FormForMyModel
的字段上定義字段。然而,這兩個字段組(類型)之間有很多相似之處,所以這是一種重複的工作。當添加標籤,驗證程序等時,相似性會增加。
- 創建
MyModel
實例有點愚蠢,必須手動分配所有這些值。
這是一個的ModelForm用武之地。
這些行爲基本上就像一個普通的形式(實際上,他們是從常規模式擴展),但他們能救我的一些工作(我剛剛概述的兩個問題當然是:))。
所以回到兩個問題:
而不是定義表單字段爲每個模型場,我只是在該Meta
類中定義model = MyModel
。這指示表單自動從模型字段生成表單字段。
模型表格有save
方法可用。這可以用來在視圖中的一行中創建模型的實例,而不是手動分配字段。
所以,讓我們對上面有ModelForm
的例子:
models.py:
class MyModel(models.Model):
field1 = models.CharField(max_length=40, blank=False, null=False)
field2 = models.CharField(max_length=60, blank=True, null=True)
forms.py:
class MyModelForm(forms.ModelForm): # extending ModelForm, not Form as before
class Meta:
model = MyModel
views.py:
def create_a_my_model(request):
if request.method == 'POST':
form = MyModelForm(request.POST)
if form.is_valid():
# save the model to database, directly from the form:
my_model = form.save() # reference to my_model is often not needed at all, a simple form.save() is ok
# alternatively:
# my_model = form.save(commit=False) # create model, but don't save to database
# my.model.something = whatever # if I need to do something before saving it
# my.model.save()
else:
form = MyModelForm()
context_data = {'form': form}
return HttpResponse('templtate.html', context_data)
希望這清除了的Django的使用形成了一個位。
只需再注意一點 - 在ModelForm
上定義表單域是完全可以的。這些將不會在form.save()
中使用,但仍可以使用form.cleaned_data
,就像使用常規表單一樣。
閱讀教程https://docs.djangoproject.com/en/dev/intro/tutorial04/?from=olddocs/和https://docs.djangoproject.com/en/dev/topics/forms/?from = olddocs。 – 2012-08-12 15:23:41
我見過這兩篇文章,我會再讀一遍。我希望瞭解表單,視圖和模板之間的關係,以及如何創建一個下拉列表..我想也許它只是帶我有時間消化..如果其他人可以騰出時間解釋這一點,我會非常高興! – Oli 2012-08-12 16:27:30