2012-04-24 41 views
2

我看到這裏的許多答案,其中超載從Django中給定的默認方法行動的建議當然是簡單地將代碼從原來的方法進行復制,並與您的修改包括在該方法中你重載版本。我的使用super()的建議不正確嗎?

例如,answer given

class MyUpdateView(UpdateView): 
    def form_valid(self, form): 
     self.object = form.save(commit=False) 
     self.object.user = self.request.user 
     self.object.save() 
     return HttpResponseRedirect(self.get_success_url()) 

    # the default implementation of form_valid is... 
    # def form_valid(self, form): 
    #  self.object = form.save() 
    #  return HttpResponseRedirect(self.get_success_url()) 

所以兩行的回答者說是默認form_valid實際上不是默認的代碼,但它們是被通過繼承執行的代碼。無論如何,他們的答案去掉form_valid任何Django的代碼向前的執行,並直接調用HttpResponseRedirect()替換它。

我會寫這個方法的方法如下:

class MyUpdateView(UpdateView): 
    def form_valid(self, form): 
     self.object = form.save(commit=False) 
     self.object.user = self.request.user 
     return super(MyUpdateView, self).form_valid(form) 

Django自己的代碼遵循這一慣例。

def form_valid(self, form): 
    self.object = form.save() 
    return super(ModelFormMixin, self).form_valid(form) 

這是form_valid真正的默認版本,這另一個問題的回答者提到:從views/generic/edit.py線111拍攝。

所以這個問題的螺帽:是否有Django的代碼做它內部的任何原因,我不應該以這種方式在我的項目使用super(),以同樣的方式?的優點,對我來說,如果Django的是永遠更新,這些觀點在內部的工作方式,有機會要好得多,我的代碼 - 它簡單地延伸,並繼續執行Django的 - 將保持兼容。另外,它使我無法通過修改現有代碼來重寫已編寫的代碼。這不是super()的預期用途之一嗎?

回答

3

是的,是有原因的。

讓我們來取代你super調用與實際的Django方法。

class MyUpdateView(UpdateView): 
    def form_valid(self, form): 
     self.object = form.save(commit=False) 
     self.object.user = self.request.user 
     self.object = form.save() # oops, we redefined self.object, user won't be saved 
     return HttpResponseRedirect(self.get_success_url()) 

所以這是行不通的。當然,使用super總是更乾燥,更好,但並非總是可行。

在從Django的來源你的例子是另一種情況:孩子不節約和家長做重定向。這裏沒有「重疊」。

+1

這只是無效的實現。我們可以將用戶設置爲form.instance.user,而不是創建將在父級調用中重寫的對象。如果我們需要所有家長的功能,那麼我們必須使用super,如果我們不需要某些部分或者想要重新定義它們(不只是添加額外的動作) - 顯然我們不需要超級。 – simplylizz 2012-04-24 07:34:29

+2

@simplylizz我認爲這會奏效,但我不喜歡這種方式。我們不用'form.save(commit = True)'的結果來處理,而是將它用作'place in change'方法。對於可讀性和對代碼的理解不太好。 – DrTyrsa 2012-04-24 07:53:02