2012-04-24 25 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ていると言うの2行は、実際にデフォルトのコードではありませんが、継承を介して実行されますコードです。それにもかかわらず、彼らの答えは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の独自のコードでは、この規則に従います。 views/generic/edit.pyライン111から撮影:

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

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

この質問のナット:super()は、私のプロジェクトでDjangoのコードが内部的に行うのと同じ方法でこのように使用するべきではありませんか?私にとっては、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を使用することは常にDRYより優れていますが、必ずしもそうとは限りません。

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

+1

これは無効です。親の呼び出しで書き換えられるオブジェクトを作成するのではなく、form.instance.userにユーザーを設定することができます。私たちがすべての親の機能を必要とするなら、いくつかのパーツを必要としないか、または特別なアクションを追加するだけでなく、それらを再定義したい場合、superを使う必要があります。 – simplylizz

+2

@simplylizzこれはうまくいくと思いますが、私はこのようには好きではありません。 'form.save(commit = True) 'の結果を扱う代わりに、' change in place'メソッドとして使用します。読みやすさとコードの理解にはあまり適していません。 – DrTyrsa

関連する問題