web-dev-qa-db-ja.com

Djangoクラスベースのビューでインスタンス変数を設定しても大丈夫ですか?

Djangoのクラスベースビュー(CBV)を試してみました。

_class BlahView(TemplateView):
    template_name = 'blah/blah.html'
    def get_context_data(self, **kwargs):
        #code...

    def get(self, request, **kwargs):
        #more code...
_

これで、self.requestからリクエストパラメータを取得できることがわかりました。ここで、これらのリクエストパラメータを解析してクラス内に保存するとします。それらを_self.xxx_に保存できますか?さて、明らかにクラスがどのように機能するかに基づいて、これは簡単に思えます。

しかし、ViewTemplateViewのスーパークラス)の定義を見て、制御の流れを理解することはできません。 source は、as_view()が「エントリポイント」であると述べています

get_context_data()の先頭にインスタンス変数を設定することを考えましたが、そこで初期化を行うのは正しくないようです。

CBVに__init__()を定義できますか?もしそうなら、スレッドの問題や、解析されたデータのグローバルインスタンスで複数のページアクセスが機能する可能性がある何かがありますか?

これは少し厄介に聞こえるかもしれませんが、CBVのコードフローと少し混乱しています。

ソース の_Django.views.generic.base.View.as_view_によると:

  • on Django startup、as_view()は関数viewを返します。これはnot呼び出されました
  • リクエストに応じてview()が呼び出されます、それクラスをインスタンス化し、dispatch()を呼び出します
  • クラスインスタンスはスレッドセーフです

source of _Django.views.generic.base.View.__init___によると、この時点ではリクエストオブジェクトはスコープ外であるため、独自のコンストラクタオーバーロードで解析することはできません。

ただし、リクエストを解析し、_Django.views.generic.base.View.dispatch_のオーバーロードでクラスビューインスタンス属性を設定することはできます。これは、 source に従って安全です。

_class YourView(SomeView):
    def dispatch(self, request, *args, **kwargs):
        # parse the request here ie.
        self.foo = request.GET.get('foo', False)

        # call the view
        return super(YourView, self).dispatch(request, *args, **kwargs)
_
45
jpic

@jpicは素晴らしい答えを提供しました。それからインスピレーションを得て、私は次のことを参照したいと思います ブログ投稿 著者が主張しているところ:

...ビューをオーバーライドすることはできません。オーバーライドするには、as_view()をオーバーライドする必要があるためです。 dispatch()をオーバーライドすることは、それを行うための単一の簡単な場所を提供するため、魅力的です(そして、この講演を最初に提示したときに私がしたこと)が、これはdispatch()のロジックに反します。代わりに、get()とpost()の両方のオーバーライドでset_account()を呼び出すのが最善です。 .。

したがって、getまたはpostメソッドをオーバーライドして、任意のself.whatever変数を設定できます。なんとなくすっきりします。

2
raratiru