2009-01-18 84 views
0

假設試圖使用django.views.generic.create_update.create_object來允許用戶訪問博客條目實例。在Entry模型中,用戶需要一個必填字段,我不希望在博客條目表單中顯示爲可編輯字段。所以,我會將它包含到EntryForm.Meta.exclude元組中。如何在使用通用視圖創建模型實例時設置模型實例的屬性?

我應該在生成的模型實例上設置用戶屬性的值?我是否必須停止使用create_object通用視圖並編寫自己的視圖?

回答

2

我不認爲你可以使用通用視圖來完成此任務,但他們對後處理數據沒有多少幫助。謝天謝地,寫出自己的觀點來做同樣的事情並不難。

(從http://www.djangobook.com/en/1.0/chapter07/改編)

from yourmodel.forms import EntryForm 

def create_entry(request): 
    if request.method == 'POST': 
     form = EntryForm(request.POST) 
     if form.is_valid(): 
      entry = form.save(commit = false) 
      entry.author = request.user.username 
      entry.save() 
      return HttpResponseRedirect('/create_entry/thanks/') 
    else: 
     form = EntryForm() 
    return render_to_response('/path/to/template.html', {'form' : form, ...}, ...) 

當然,你必須使用你自己的名字和這樣的,但是這就是邏輯。基本上你會檢查一個表單是否已經提交,如果是這樣的話就得到條目,添加一個用戶名並像往常一樣保存。就通用create_object視圖而言,不同於視圖調用中指定諸如post_redirect_url之類的內容,您可以直接給予它們。查看render_to_response和HttpResponseRedirect的文檔以獲取更多信息。

0

sykora的解決方案有一個小問題:如果表單無效,您將得到一個錯誤,因爲表單不會被設置(在if語句的範圍之外)。

這裏有一個稍微好一點的版本:

from yourmodel.forms import EntryForm 

def create_entry(request): 
    form = EntryForm() 
    if request.method == 'POST': 
     form = EntryForm(request.POST) 
     if form.is_valid(): 
      entry = form.save(commit = false) 
      entry.author = request.user.username 
      entry.save() 
      return HttpResponseRedirect('/create_entry/thanks/') 
    return render_to_response('/path/to/template.html', {'form' : form, ...}, ...) 
1

我必須解決這個問題,並沒有想欺騙。這並不難。檢查下面。

請注意,這只是這個錯綜複雜,因爲我選擇堅持我對MVC分離的看法。用戶羣體是特定於視圖的(因爲我們在Edit中沒有特殊的初始用戶)。處理是特定於模型的。

提取表單mixin並不難,它需要一個新的「passthrough」參數,並自動將排除與轉發初始數據合併。這也增加了認識無人可以修改視圖中這些字段數據的安全性。

class TestForm(forms.ModelForm): 

    class Meta: 
     exclude = ('user') 
     model = models.Test 

    def save(self, commit=True): 
     obj = super(CharmForm, self).save(commit=False) 
     obj.user = self.initial['user'] 

     if commit: 
      obj.save() 

class TestView(CreateView): 
    model = models.Test 
    form_class = TestForm 
    def get_initial(self,**kwargs): 
     initial = super(CreateView,self).get_initial() 

     c = RequestContext(self.request) 

     initial = initial.copy() 
     initial['user'] = c['user'] 
     return initial 

此外,不完全確定您是否嘗試使用新的基於類的視圖。我實際上是回答這個問題的任何人有這個問題(我不得不破解代碼來找到答案,因爲沒有人似乎已經做到了這一點)。

相關問題