简体   繁体   English

坚持Django FormView数据

[英]Persist Django FormView Data

I have a FormView that generates a review of an object (which it is generically related to) and then links it to the object and saves it when the form is completed. 我有一个FormView,它生成一个对象的评论(通常与之相关),然后将其链接到该对象,并在表单完成时保存它。

The issue I'm having is that I have no way to hold onto the data of the object I want to connect to. 我遇到的问题是我无法保留要连接的对象的数据。 This means that I need to 'look it up' for context (template rendering) for valid processing (to do the linking) and for the success (to generate an appropriately reversed url. 这意味着我需要针对上下文(模板渲染)进行“查找”,以进行有效处理(进行链接)并获得成功(生成适当的反向URL)。

Is there a better way to be binding the review to the object? 有没有更好的方法将评论绑定到对象? Or better yet, is there a way to persist form data that I'm missing? 或更妙的是,有没有一种方法可以保留我丢失的表单数据?

EDIT: Sorry the login decorator was on dispatch. 编辑:对不起,登录装饰器已调度。 I removed that method because SO was complaining about too much code and I didn't think it was relevant... I must have missed the decoratot 我删除了该方法,因为SO抱怨太多的代码,我不认为这是相关的...我一定错过了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},)

The view is an object right, so you just assign your values to instance variables, ie "to self" ( this is thread-safe ). 该视图是一个对象权限,因此您只需将值分配给实例变量,即“ to self”( 这是线程安全的 )。 Like this: 像这样:

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
            },
        )

The default form_valid() method for FormView redirects to the success url and reinitializes the form. FormView的默认form_valid()方法将重定向到成功URL并重新初始化表单。 You can make the form data persist by overriding form_valid() : 您可以通过覆盖form_valid()使表单数据持久化:

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

This will redirect to your success url with a (bounded) form having the posted data. 这将使用包含已发布数据的(有界)表单重定向到您的成功网址。 The form is added to the context so you can use the data in your template or in your view as you wish. 表单被添加到上下文中,因此您可以根据需要在模板或视图中使用数据。

(Django version 1.11.7) (Django版本1.11.7)

The get_context_data should always return the context dictionary. get_context_data应该始终返回上下文字典。 It doesn't make sense to use the login_required decorator with it, because that means it might return a redirect response instead. 与其一起使用login_required装饰器是没有意义的,因为这意味着它可能会返回重定向响应。

It would be better decorate the dispatch method instead. 最好装饰一下dispatch方法。 In your dispatch , you can set attributes on the instance. 在您的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)

Then, in your other methods, you can access the attributes, for example: 然后,在其他方法中,您可以访问属性,例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM