来自get_queryset的Django基于类的视图访问上下文数据

时间:2016-06-22 04:27:41

标签: python django

class ProfileContextMixin(generic_base.ContextMixin, generic_view.View):

    def get_context_data(self, **kwargs):
        context = super(ProfileContextMixin, self).get_context_data(**kwargs)
        profile = get_object_or_404(Profile, user__username=self.request.user)
        context['profile'] = profile
        return context

class CourseListView(ProfileContextMixin, generic_view.ListView):
    model = Course
    template_name = 'course_list.html'
    object_list = None

    def get_queryset(self):
        profile = self.get_context_data()['profile']
        return super(CourseListView, self).get_queryset().filter(creator=profile)

我有以下两个基于类的视图。 CourseListView继承了我编写的ProfileContextMixin,因此我不必重复覆盖get_context_data以便在我的其他视图中每次都获得profile

现在在我的CourseListView中,我需要根据creator参数过滤结果,该参数与get_context_data中检索到的相同

我知道我的get_queryset有效,它会调用get_context_data()来获取配置文件,但这也会导致我的get_context_data被调用两次,执行相同的SQL两次。

有没有办法可以有效地访问上下文?

更新

在阅读ListView方法流程图之后,我最终做到了这一点,但不确定这是否是最好的方法。感谢您的反馈。

    object_list = []
    context = None

    def get_context_data(self, **kwargs):
        return self.context

    def get_queryset(self):
        self.context = super(CourseListView, self).get_context_data()
        profile = self.context['profile']
        queryset = super(CourseListView, self).get_queryset()
        queryset = queryset.filter(creator=profile)
        self.context['object_list'] = queryset
        return queryset

1 个答案:

答案 0 :(得分:1)

您可以将get_context_data的个人资料转移到更高级别的功能,例如dispatch,或使用cached_property装饰器。这样,您的个人资料将存储在_profile参数视图中,并且在第二次调用get后,您不会再向self.profile发送from django.utils.functional import cached_property class ProfileContextMixin(generic_base.ContextMixin, generic_view.View): @cached_property def profile(self): return get_object_or_404(Profile, user__username=self.request.user) def get_context_data(self, **kwargs): context = super(ProfileContextMixin, self).get_context_data(**kwargs) context['profile'] = self.profile return context class CourseListView(ProfileContextMixin, generic_view.ListView): model = Course template_name = 'course_list.html' object_list = None def get_queryset(self): return super(CourseListView, self).get_queryset().filter(creator=self.profile)

name="myFrame"