2011-08-02 7 views
12

私はFormViewクラスから派生したクラスQuestionViewを持っています。ここ 私の問題を説明するためのコードスニペットです:FormViewでコンテキストデータを更新するform_valid method?

class QuestionView(FormView): 
    ... 
    context_var1 = y 
    def form_valid (self, form): 
    ... 
    self.context_var1 = x 
    ... 
    def get_context_data(self, **kwargs): 
    ... 
    context['context_var1'] = self.context_var1 
    ... 
    return context 

上に示したように、私はform_validと にコンテキスト変数のセットを更新し、私は、テンプレート内のこれらの更新された値を使用する予定 - したがって、変数内をcontext辞書。このコードの問題はがform_validメソッドの前に呼び出された なので、 context_var1の変更が見られない可能性があります。 の回避策はありますか?

答えて

25

form_invalidでこれを行います。ここで私はそれをやっている:

from django.views.generic import FormView 

class ContextFormView(FormView): 
    def get(self, request, *args, **kwargs): 
     form_class = self.get_form_class() 
     form = self.get_form(form_class) 
     context = self.get_context_data(**kwargs) 
     context['form'] = form 
     return self.render_to_response(context) 

    def post(self, request, *args, **kwargs): 
     form_class = self.get_form_class() 
     form = self.get_form(form_class) 
     if form.is_valid(): 
      return self.form_valid(form) 
     else: 
      return self.form_invalid(form, **kwargs) 

    def form_invalid(self, form, **kwargs): 
     context = self.get_context_data(**kwargs) 
     context['form'] = form 
     return self.render_to_response(context) 

同じことをすることができますが、form_valid。通常form_validの体は次のようになります。

def form_valid(self, form): 
    return HttpResponseRedirect(self.get_success_url()) 

あなたは両方postform_validpostためのコールform_validを上書きする必要があります。

def post(self, request, *args, **kwargs): 
    form_class = self.get_form_class() 
    form = self.get_form(form_class) 
    if form.is_valid(): 
     return self.form_valid(form, **kwargs) 
    else: 
     return self.form_invalid(form, **kwargs) 

def form_valid(self, form, **kwargs): 
    # take some other action here 
    return HttpResponseRedirect(self.get_success_url()) 

ああ、ちょうど明確にするために、この問題が存在する理由は、ProcessFormViewクラスのgetメソッドが壊れているということです。これは、通常、次のようになります。

def get(self, request, *args, **kwargs): 
    form_class = self.get_form_class() 
    form = self.get_form(form_class) 
    return self.render_to_response(self.get_context_data(form=form)) 

それはちょうどたぶん、あなたは、このアプローチを使用することができます離れて(._.)

+2

ありがとうございました。 2年後、Djangoはまだform_validまたはform_invalidでコンテキストを更新する方法を提供していません。 – pymarco

+0

そしてdjango 1.7でも:( – vinyll

+1

Django 1.8はform_validでコンテキストを更新する方法を提供していますか? –

0

kwargsからのスロー:では

class SomeView(View): 

    def post(self, request): 
     my_form = MyForm(request.POST) 
     if my_form.is_valid(): 
      context['foo'] = 'bar' 

     return render(request, 'valid/path.html', context) 
1
views.py

class UploadTest(FormView): 
    template_name = 'test.html' 
    .... 
    plus_context = dict() 

    def form_valid(self, form): 
     ... 
     self.plus_context['you_want_context'] = value 
     ... 
     return super(UploadTest, self).form_valid(form) 

    def get_context_data(self, **kwargs): 
     context = super(UploadTest, self).get_context_data(**kwargs) 
     context['plus_context_key'] = self.plus_context 
     return context 

をtest.html

<html> 
    .... 
    <body> 
    .... 
    // first post can not get plus_context_key 
    {% if plus_context_key %} 
     {{ plus_context_key.you_want_context }} 
    {% endif %}  
    </body> 
</html> 

私はちょうどDjango 1.10.3でこのように考えています。 希望はあなたを助けることができます

+0

フォームがそれ自身にリダイレクトされた場合、これはフォームビューに 'GET'があっても' plus_context_key'の内容を表示します。これを回避するには、 'context ['plus_context_key'] = self.plus_context'の後に' self.plus_context = dict() 'を使用して、後で' GET' – shadi

0

Django 2.0.1でget_context_dataまたはform_invalidのいずれかを上書きしてコンテキストデータを挿入できます。

次の上書きのいずれかを行うことができますあなたの場合は

class QuestionView(FormView): 
    ... 

    def form_invalid(self, form): 
     """If the form is invalid, render the invalid form.""" 
     return self.render_to_response(
      self.get_context_data(
       form=form, 
       context_key=some_value 
      ) 
     ) 

または:

class QuestionView(FormView): 
    ... 

    def get_context_data(self, **kwargs): 
     if 'context_key' not in kwargs: # set value if not present 
      kwargs['context_key'] = some_value 
     return super().get_context_data(**kwargs) 

Djangoはフードget_context_dataのkwargsからにフォームの下に挿入を2.0.1。

# File: django.views.generic.edit 

class FormMixin(ContextMixin): 
    ... 

    def form_valid(self, form): 
     """If the form is valid, redirect to the supplied URL.""" 
     return HttpResponseRedirect(self.get_success_url()) 

    def form_invalid(self, form): 
     """If the form is invalid, render the invalid form.""" 
     return self.render_to_response(self.get_context_data(form=form)) 

    def get_context_data(self, **kwargs): 
     """Insert the form into the context dict.""" 
     if 'form' not in kwargs: 
      kwargs['form'] = self.get_form() 
     return super().get_context_data(**kwargs) 
関連する問題