2

Djangoから特定のデフォルトメソッドをオーバーロードする際の推奨されるアクションは、元のメソッドからコードをコピーし、オーバーロードされたバージョンのメソッドにコードを含めることです。

たとえば、次のような答えがあります。

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())

したがって、回答者がデフォルトであると言う2行は、form_valid実際にはデフォルトのコードではありませんが、継承によって実行されるコードです。とにかく、彼らの答えは、Djangoコードの実行を前に削除し、直接呼び出しform_validに置き換えました。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独自のコードは、この規則に従います。views/generic/edit.py111行目から取得:

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

form_validこれは、この他の質問の回答者が参照している真のデフォルトバージョンです。

したがって、この質問の要点は、Djangoのコードが内部で使用するのと同じように、プロジェクトでこのように使用すべきではない理由はありますか?super()私にとっての利点は、これらのビューが内部で機能する方法をDjangoが更新した場合、Djangoを拡張して実行し続ける私のコードの互換性が維持される可能性がはるかに高いことです。さらに、既存のコードを変更して実行するだけで、すでに記述されているコードを書き直すことができなくなります。これは、の使用目的の1つではありませんsuper()か?

4

1 に答える 1

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は常に DRY'er であり、より優れていますが、常に可能であるとは限りません。

Django ソースの例では、別の状況です。子が保存を行い、親がリダイレクトを行います。ここには「重複」はありません。

于 2012-04-24T07:21:09.467 に答える