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)
I have the following two class-based-views. CourseListView
inherits ProfileContextMixin
which I wrote so that I don't have to repeat overriding get_context_data
to get the profile
every time in my other views.
Now in my CourseListView
, I need to filter the result based on the creator
argument, which is the same one retrieved in get_context_data
I know my get_queryset
works, and it will call get_context_data()
to get the profile, but this will also cause my get_context_data
to be called twice, executing the same SQL two times.
Is there a way I can access the context efficiently?
UPDATE:
After reading ListView
method flowchart, I ended up doing this, but not sure if it's the best way. Feedback is appreciated.
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
You can move getting profile out of get_context_data
to upper function, like dispatch
, or use cached_property
decorator. This way your profile will be stored in _profile
argument of view and you will not do second get
to DB after calling self.profile
second time.
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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.