2011-08-02 17 views
12

我有一個類QuestionView這是從FormView類派生。這裏 是一個代碼片段來解釋我的問題:在FormView form_valid方法中更新上下文數據?

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字典。此代碼的問題在於未看到 context_var1中的更改 - 可能是因爲get_context_data是 在form_valid方法之前調用。是否有針對 的解決方法?

回答

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_valid,因爲post電話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)) 

它只是拋出kwargs遠(._.)

+2

感謝您的解決方案。兩年後,Django仍然沒有提供更新form_valid或form_invalid中的上下文的方法。 – pymarco

+0

而在Django 1.7中:( – vinyll

+1

Do Django 1.8提供了一種更新form_valid中的上下文的方法? –

0

也許你可以使用這種方法:

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_dataform_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 2.0.1插入引擎蓋下的形式進入的get_context_data的kwargs。

# 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) 
相關問題