Last active
May 17, 2016 21:00
-
-
Save numan/6097492 to your computer and use it in GitHub Desktop.
Custom model resource for caching django-tastypie responses with django-cache-machine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from caching.invalidation import make_key | |
from functools import partial | |
def get_response_key(request): | |
smooshed = [] | |
cache_keys = request.GET.keys() | |
cache_keys.sort() | |
for key in cache_keys: | |
smooshed.append(u"{}={}".format(key, request.GET[key])) | |
smooshed.append(u"HTTP_ACCEPT={}".format(request.META["HTTP_ACCEPT"])) | |
return make_key(u'api:v1:{}:{}'.format(request.path, smooshed), with_locale=False) | |
def get_response_key(request): | |
""" | |
Generate a unique key for each request. | |
""" | |
smooshed = [] | |
cache_keys = request.GET.keys() | |
cache_keys.sort() | |
for key in cache_keys: | |
smooshed.append(u"{}={}".format(key, request.GET[key])) | |
smooshed.append(u"HTTP_ACCEPT={}".format(request.META["HTTP_ACCEPT"])) | |
return make_key(u'api:{}:{}'.format(request.path, smooshed), with_locale=False) | |
class CachingModelResource(ModelResource): | |
def create_cached_response(self, request, data, response_class=HttpResponse, **response_kwargs): | |
""" | |
Like ``create_response`` but assumes the data has already been serialized | |
""" | |
desired_format = self.determine_format(request) | |
return response_class(content=data, content_type=build_content_type(desired_format), **response_kwargs) | |
def create_response_content(self, to_be_serialized=None, request=None): | |
# Dehydrate the bundles in preparation for serialization. | |
bundles = [] | |
for obj in to_be_serialized[self._meta.collection_name]: | |
bundle = self.build_bundle(obj=obj, request=request) | |
bundles.append(self.full_dehydrate(bundle, for_list=True)) | |
to_be_serialized[self._meta.collection_name] = bundles | |
to_be_serialized = self.alter_list_data_to_serialize(request, to_be_serialized) | |
response = self.create_response(request, to_be_serialized) | |
return response.content | |
def get_list(self, request, **kwargs): | |
""" | |
Overriden mostly to modify how the response is generated. | |
Returns a serialized list of resources. | |
Calls ``obj_get_list`` to provide the data, then handles that result | |
set and serializes it. | |
Should return a HttpResponse (200 OK). | |
""" | |
#****** Start Copy/Paste from Tastypie********* | |
# TODO: Uncached for now. Invalidation that works for everyone may be | |
# impossible. | |
base_bundle = self.build_bundle(request=request) | |
objects = self.obj_get_list(bundle=base_bundle, **self.remove_api_resource_names(kwargs)) | |
sorted_objects = self.apply_sorting(objects, options=request.GET) | |
paginator = self._meta.paginator_class(request.GET, sorted_objects, resource_uri=self.get_resource_uri(), limit=self._meta.limit, max_limit=self._meta.max_limit, collection_name=self._meta.collection_name) | |
to_be_serialized = paginator.page() | |
#****** END Copy/Paste from Tastypie********* | |
#Get the queryset for the response | |
final_qs = to_be_serialized[self._meta.collection_name] | |
#Use cached_with to cache the response content | |
create_response_content = partial(self.create_response_content, request=request, to_be_serialized=to_be_serialized) | |
response = self.create_cached_response( | |
request, cached_with( | |
final_qs, create_response_content, get_response_key(request), timeout=3600)) | |
return response |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment