2016-03-05 93 views
1

我有一个FormView生成一个对象的审查(它通常与之相关),然后将它链接到对象并在表单完成时保存它。Persist Django FormView数据

我遇到的问题是我没有办法保持我想连接的对象的数据。这意味着我需要为上下文(模板呈现)进行“查找”,以进行有效处理(进行链接)和成功(生成适当的反向url)。

有没有更好的绑定方法审查的对象?或更好的是,有没有办法坚持形式的数据,我失踪了?

编辑:对不起,登录装饰派遣。我删除该方法,因为太抱怨太多的代码我不认为这是相关的...我一定错过了decoratot

class ReviewCreate(FormView): 
    template_name = 'food/item_add_review.html' 
    form_class = ReviewForm 
    review_item = None 


    def get_context_data(self, **kwargs): 
     context = super(ReviewCreate, self).get_context_data(**kwargs) 

     item_modelname = self.kwargs.get('model') 
     item_model = apps.get_model('food',item_modelname) 
     review_item = get_object_or_404(item_model,pk=self.kwargs.get('pk')) 

     context['item'] = review_item 

     return context 

    def form_valid(self, form): 
     item_modelname = self.kwargs.get('model') 
     item_model = apps.get_model('food',item_modelname) 
     review_item = get_object_or_404(item_model,pk=self.kwargs.get('pk')) 

     r = form.save(commit=False) 

     r.content_object=review_item 
     r.save() 

     return super(ReviewCreate, self).form_valid(form) 

    def get_success_url(self): 
     item_modelname = self.kwargs.get('model') 
     item_model = apps.get_model('food',item_modelname) 
     review_item = get_object_or_404(item_model,pk=self.kwargs.get('pk')) 

     return reverse('pkitem', kwargs = {'pk': review_item.id, 'model':item_modelname},) 

回答

1

该视图是一个对象的权利,所以你只是分配给你r值转换为实例变量,即“自我”(this is thread-safe)。像这样:

class ReviewCreate(FormView): 
    template_name = 'food/item_add_review.html' 
    form_class = ReviewForm 

    @method_decorator(login_required) # Use a class level mixin instead 
    def get_context_data(self, **kwargs): 
     return super(
      ReviewCreate, 
      self 
     ).get_context_data(
      item=self.review_item, 
      **kwargs 
     ) 

    def lookup_review_item(self): 
     self.item_modelname = self.kwargs.get('model') 
     item_model = apps.get_model('food', self.item_modelname) 
     self.review_item = get_object_or_404(
      item_model, 
      pk=self.kwargs.get('pk') 
     ) 

    def dispatch(self, request, *args, **kwargs): 
     # lookup performed here to be set for both GET and POST 
     self.lookup_review_item() 
     return super(ReviewCreate, self).dispatch(request, *args, **kwargs) 

    def form_valid(self, form): 
     r = form.save(commit=False) 
     r.content_object=self.review_item 
     r.save() 
     return super(ReviewCreate, self).form_valid(form) 

    def get_success_url(self): 
     return reverse(
      'pkitem', 
      kwargs = { 
       'pk': self.review_item.id, 
       'model': self.item_modelname 
      }, 
     ) 
+0

我曾尝试改变自我。*在get_context_data位变量没有坚持......虽然这是更优雅是存在的,没有工作,明显的原因? – Ewanw

+0

如果self.review_item没有设置,get_context_data会引发AttributeError。我会仔细检查模板。 –

0

get_context_data应该总是返回上下文字典。装饰器使用login_required修饰器没有意义,因为这意味着它可能会返回重定向响应。

而不是装饰dispatch方法。在你的dispatch中,你可以设置实例的属性。

class ReviewCreate(FormView): 

    @method_decorator(login_required) 
    def dispatch(self, request, *args, **kwargs): 
     self.item_modelname = self.kwargs.get('model') 
     self.item_model = apps.get_model('food',item_modelname) 
     self.review_item = get_object_or_404(item_model,pk=self.kwargs.get('pk')) 
     return super(ReviewCreate, self).dispatch(request, *args, **kwargs) 

然后,在你其他的方法,你可以访问的属性,例如:

def get_context_data(self, **kwargs): 
     context = super(ReviewCreate, self).get_context_data(**kwargs) 
     context['item'] = self.review_item 
     return context 
0

FormView默认form_valid()方法重定向到成功URL并重新初始化形式。您可以将表单数据持续通过重写form_valid()

def form_valid(self, form): 
    return super(YourFormView, self).get(form) 

这将重定向到您的成功网址与具有发布的数据(界)的形式。表单将添加到上下文中,以便您可以根据需要在模板或视图中使用数据。

(Django的版本1.11.7)