素朴な疑問なのですが、以下のようにget_context_data()内のcontextをself.contextとして
クラス内で使い回すのって良いでしょうか?
class IndexView( TemplateView ): template_name = "books/index.html" def get_context_data( self, **kwargs ): self.context = super().get_context_data( **kwargs ) form = PublisherCreateForm( self.request.POST or None ) self.context['form'] = form self.context['formset'] = BookCreateFormFormset() return self.context def post( self, form ): form = PublisherCreateForm( self.request.POST or None ) if form.is_valid(): publisher = form.save( commit = False ) bookformset = BookCreateFormFormset( self.request.POST, instance = publisher ) if bookformset.is_valid(): publisher.save() bookformset.save() return redirect( 'books:index' ) else: self.context['formset'] = bookformset
良くないと思いますよ。
■Viewがリクエスト単位で破棄されるものであった場合
同じリクエスト内であればself内に何かを保存し、参照することに問題はありません。ただし、別メソッドが参照するタイミングがあるなら、それは別スレッドとかになるのではないかと思います。同一スレッドなら素直に引数や戻り値で渡せばいいので...
■Viewがリクエスト単位で破棄されるものでなかった場合
複数のリクエストで1つのコンテキストを参照することになってしまいます。
例えば、ユーザーAとユーザーBが別セッションからどちらかのコンテキストを参照することになってしまうでしょうね。
仮にリクエストがスレッドで処理される場合は、セッションでなかったとしても、2つのリクエストが処理するコンテキストが同じになってしまい、困ると思います。
ちゃんと調べてないので曖昧な話になってすみません。
https://docs.djangoproject.com/en/dev/ref/class-based-views/#specification
"Each request served by a class-based view has an independent state; therefore, it is safe to store state variables on the instance (i.e., self.foo = 3 is a thread-safe operation)."
だそうなので、上記「Viewがリクエスト単位で破棄されるものであった場合」に近そうで、問題はなさそうです。利便性などの都合で同一スレッドでも属性に保管したりするのかもしれません。
色々とお調べいただき本当にありがとうございました。
self.context = super().get_context_data( **kwargs )
のようにself を付けなかった場合ですが、
dameo様であればどのように post() 内でhtml側に formset を返しますか...?
( いま記述している self.context['formset'] = bookformset の箇所をself,cintext を用いずに表現する場合はdameo様であればどのようになるのかなと...)
djangoはまともに使ったことがないので、今までセッションを使った実装が必要なかったのですよ。
ただリクエストにまたがるデータならセッションを使います。
それで駄目ならデータをページに埋め込んでhiddenでもいいからまた送ってもらいます。
セッションは少し実装してみないと分からないので、お返事は気が向いたときになっちゃいます。
よく考えたら前回リクエストにまたがってるわけではなさそうだという調査結果でしたね。
セッションは必要ないかも・・・
ただこのソース何をしてるのかよく分かりません。BookCreateFormFormsetとは何ですか?
postの引数formとは何が違うんでしょう?
なんでrequest.POSTを入れてるんですか?
invalidだった場合、self経由で作り直したbookformsetを入れてない場合どうなるんでしょう?
必要性がよく分かりません。私が知らないだけかもですけど。