2012-08-12 72 views
13

我正在努力讓我的頭圓形django形式..我一直在閱讀各種文檔,但不能完全理解的概念。我必須掌握模型,視圖和模板。我想要做的是創建一個窗體,其中包含由數據庫中的值填充的下拉列表和複選框組成的各種字段。創建django表單

我有一個名爲vms的工作應用程序。使用models.py我有一個簡單的模式,包含大小和類型。大小包括「小」,「中」&「大」。類型是'windows'&'linux'。使用管理網站,我可以添加額外的大小,例如「超大」。

我想要做的是創建一個窗體,它具有vm大小的下拉列表。如果通過管理站點添加了額外的大小,我希望該大小出現在下拉列表中。

我會在代碼中提交我的嘗試,但實際上我正在努力應對這些概念。任何人都可以幫助指導我如何完成上述?

感謝 奧利

+2

閱讀教程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

+0

我見過這兩篇文章,我會再讀一遍。我希望瞭解表單,視圖和模板之間的關係,以及如何創建一個下拉列表..我想也許它只是帶我有時間消化..如果其他人可以騰出時間解釋這一點,我會非常高興! – Oli 2012-08-12 16:27:30

回答

30

表單只是簡化和加速(開發)從請求中獲取POST數據的過程的工具。手動的方式是爲所有的字段做一些HTML格式的request.POST.get('somefield')。但是Django的可以做的比這更好的...

在本質上,一個Form類包含若干領域,並執行以下任務:

  1. 顯示HTML輸入,
  2. 收集和驗證數據時用戶提交它
  3. 如果字段不驗證,則返回值和錯誤消息爲HTML
  4. 如果所有字段都是有效的,請提供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的可以做的比這更好的...

您可以注意到在上面例如兩個惱人的問題:

  1. 我有分別在MyModelFormForMyModel的字段上定義字段。然而,這兩個字段組(類型)之間有很多相似之處,所以這是一種重複的工作。當添加標籤,驗證程序等時,相似性會增加。
  2. 創建MyModel實例有點愚蠢,必須手動分配所有這些值。

這是一個的ModelForm用武之地。

這些行爲基本上就像一個普通的形式(實際上,他們從常規模式擴展),但他們能救我的一些工作(我剛剛概述的兩個問題當然是:))。

所以回到兩個問題:

  1. 而不是定義表單字段爲每個模型場,我只是在該Meta類中定義model = MyModel。這指示表單自動從模型字段生成表單字段。

  2. 模型表格有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,就像使用常規表單一樣。

+0

嗨 - 感謝您的帖子。我現在要給出一個解決方案,我會隨着進展回到你身邊 - 事實上我發現你的文章與我讀過的一些文檔相似,但你已經包含了一些明確的例子。這一定會幫助把它放在一起..希望很快會到達那裏.. – Oli 2012-08-12 19:06:29

+1

嘿 - 我的表單現在工作..在第一個障礙 - 感謝您的幫助。連同這個問題中的例子,docs.djangoproject.com/en/dev/intro/tutorial04/?from=olddocs和docs.djangoproject.com/en/dev/topics/forms/?from=olddocs和這個網站, peachybits.com/2011/09/django-1-3-form-api-modelform-example我能夠解決這個問題。 – Oli 2012-08-13 14:42:23

2

你有沒有試着用ModelForms前的工作?據我瞭解,你正在尋找創建一個基於你創建的模型的表單嗎?

可以說你的模型叫做Temp。您可以創建與此模型(和你的問題)相關形式是這樣的:

forms.py

from django.forms import ModelForm 

class TempForm(ModelForm): 
    class Meta: 
    model = Temp 

的的ModelForm會從模型的選擇/選擇自動映射到一個表單版本。

如果你打算在模板中使用這個以後,做這樣的事情會自動創建一個選項的下拉菜單:

<form> 
    <label for="id_size">Size</label> 
    {{ form.size }} 
</form> 

希望這回答您的問題!

+1

感謝您的回答..我會盡力讓這一切。我實際上遇到了這個網站,http://www.peachybits.com/2011/09/django-1-3-form-api-modelform-example/,即使它是django 1.3,我可以看到使用的概念。當我理解你的例子時,我會回到你身邊。剛剛克服最初的障礙似乎很難,但一旦得到它,我相信它會輕鬆流動。 – Oli 2012-08-12 19:03:45

+0

嘿 - 我的表單現在可以工作了。在第一關 - 感謝您的幫助。連同這個問題中的例子,docs.djangoproject.com/en/dev/intro/tutorial04/?from=olddocs和docs.djangoproject.com/en/dev/topics/forms/?from=olddocs和這個網站, peachybits.com/2011/09/django-1-3-form-api-modelform-example我能夠解決這個問題。 – Oli 2012-08-13 14:42:05