【问题标题】:Accessing a context object in a Django class-based generic view在基于 Django 类的通用视图中访问上下文对象
【发布时间】:2011-08-14 11:11:56
【问题描述】:

我正在使用 DetailView 来查看 Project 对象,并且我希望能够访问正在查看的 Project 对象以便将其传递给装饰器,如下所示:

class ProjectDetailView(DetailView):
    context_object_name = "project"
    model = Project

    @method_decorator(membership_required(project))
    def dispatch(self, *args, **kwargs):
        return super(ProjectDetailView, self).dispatch(*args, **kwargs)

但是,将“项目”或“对象”传递给装饰器会给我一个“对象”,而不是项目实例。如何获取该 Project 实例,以便我的装饰器函数可以使用它?

【问题讨论】:

    标签: django django-generic-views django-class-based-views


    【解决方案1】:

    对象是在 dispatch() 方法中检索的,所以你的装饰器不能使用它。 您可以在覆盖的 get() 方法中检查成员资格:

    class ProjectDetailView(DetailView):
        context_object_name = "project"
        model = Project
    
        def get(self, request, **kwargs):
            self.object = self.get_object()
            if not self.object.is_member(self.request.user):
                return HttpResponseRedirect('/') # or something else
            context = self.get_context_data(object=self.object)
            return self.render_to_response(context)
    

    如果您想坚持使用装饰器,则必须根据参数(id 或 slug)从装饰器内的数据库中检索对象以进行查看。但是您将从数据库中检索对象两次,首先是在您的装饰器中,然后是在视图中。

    【讨论】:

    • 你能告诉我为什么我需要使用self.request.user 而不是只使用request.user 吗?我用request.user 尝试了代码,它成功了,但我不知道这是不是巧合。
    • 是的,你可以使用request.user,因为它是作为参数传递给方法的。我只是没有注意到。通常,当我在基于类的视图中覆盖方法时,它们不会将请求作为参数(get_context_dataget_query_setget_object 等方法)。
    猜你喜欢
    • 2014-10-12
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    • 2011-10-31
    • 2011-09-19
    • 1970-01-01
    • 2013-01-26
    • 2014-01-08
    相关资源
    最近更新 更多