假設試圖使用django.views.generic.create_update.create_object來允許用戶訪問博客條目實例。在Entry模型中,用戶需要一個必填字段,我不希望在博客條目表單中顯示爲可編輯字段。所以,我會將它包含到EntryForm.Meta.exclude元組中。如何在使用通用視圖創建模型實例時設置模型實例的屬性?
我應該在生成的模型實例上設置用戶屬性的值?我是否必須停止使用create_object通用視圖並編寫自己的視圖?
假設試圖使用django.views.generic.create_update.create_object來允許用戶訪問博客條目實例。在Entry模型中,用戶需要一個必填字段,我不希望在博客條目表單中顯示爲可編輯字段。所以,我會將它包含到EntryForm.Meta.exclude元組中。如何在使用通用視圖創建模型實例時設置模型實例的屬性?
我應該在生成的模型實例上設置用戶屬性的值?我是否必須停止使用create_object通用視圖並編寫自己的視圖?
我不認爲你可以使用通用視圖來完成此任務,但他們對後處理數據沒有多少幫助。謝天謝地,寫出自己的觀點來做同樣的事情並不難。
(從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的文檔以獲取更多信息。
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, ...}, ...)
我必須解決這個問題,並沒有想欺騙。這並不難。檢查下面。
請注意,這只是這個錯綜複雜,因爲我選擇堅持我對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
此外,不完全確定您是否嘗試使用新的基於類的視圖。我實際上是回答這個問題的任何人有這個問題(我不得不破解代碼來找到答案,因爲沒有人似乎已經做到了這一點)。