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
答案 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"