Caching based on dynamic data

Many times you will want to cache something that is based on dynamic data. In these cases, you have to build dynamic keys that contain all information required to uniquely identify the cached data. Edit the views.py file of the courses application and modify the CourseListView view to make it look like this:

class CourseListView(TemplateResponseMixin, View):
model = Course
template_name = 'courses/course/list.html'

def get(self, request, subject=None):
subjects = cache.get('all_subjects')
if not subjects:
subjects = Subject.objects.annotate(
total_courses=Count('courses'))
cache.set('all_subjects', subjects)
all_courses = Course.objects.annotate(
total_modules=Count('modules'))
if subject:
subject = get_object_or_404(Subject, slug=subject)
key = 'subject_{}_courses'.format(subject.id)
courses = cache.get(key)
if not courses:
courses = all_courses.filter(subject=subject)
cache.set(key, courses)
else:
courses = cache.get('all_courses')
if not courses:
courses = all_courses
cache.set('all_courses', courses)
return self.render_to_response({'subjects': subjects,
'subject': subject,
'courses': courses})

In this case, we also cache both all courses and courses filtered by subject. We use the all_courses cache key for storing all courses if no subject is given. If there is a subject, we build the key dynamically with 'subject_{}_courses'.format(subject.id).

It is important to note that you cannot use a cached QuerySet to build other QuerySets, since what you cached are actually the results of the QuerySet. So you cannot do the following:

courses = cache.get('all_courses')
courses.filter(subject=subject)

Instead, you have to create the base QuerySet Course.objects.annotate(total_modules=Count('modules')), which is not going to be executed until it is forced, and use it to further restrict the QuerySet with all_courses.filter(subject=subject) in case the data was not found in the cache.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset