标签:django cache tastypie 缓存 redis
这就算是第一篇博客了,我老大陈如杰(一个牛逼的程序员)讲过,只有自己研究了的东西才能写到博客上,我谨遵教诲。
环境:Django==1.8.2、django-tastypie==0.12.2-dev、redis==2.10.3、django-redis==4.1.0
django配置了使用redis作为后台缓存
在ubuntu中安装了redis-server(sudo apt-get install redis-server),在django的settings中加入如下配置:(具体可以参考http://niwinz.github.io/django-redis/latest/)
# to set django‘s default cache add by minkedong CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/1", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } }
在写tastypie自己的ModelResource时,在Meta中加入:
cache = SimpleCache(timeout=8*60*60)
当我请求此ModelResource的时候,发出GET请求“/api/v1/author/1/”后,在ubuntu的bash中使用命令:redis-cli -n 1 进入redis,在redis中键入命令:keys *,查看到已经缓存了此API的请求结果。
但当我发出GET请求"/api/v1/author/"后,进入redis查看,发现并没有缓存我的结果。
果断进入tastypie的源码查看,在"tastypie.resources.ModelResource"中有如下两个方法:
def get_list(self, request, **kwargs): """ 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). """ # 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() # 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) return self.create_response(request, to_be_serialized) def get_detail(self, request, **kwargs): """ Returns a single serialized resource. Calls ``cached_obj_get/obj_get`` to provide the data, then handles that result set and serializes it. Should return a HttpResponse (200 OK). """ basic_bundle = self.build_bundle(request=request) try: obj = self.cached_obj_get(bundle=basic_bundle, **self.remove_api_resource_names(kwargs)) except ObjectDoesNotExist: return http.HttpNotFound() except MultipleObjectsReturned: return http.HttpMultipleChoices("More than one resource is found at this URI.") bundle = self.build_bundle(obj=obj, request=request) bundle = self.full_dehydrate(bundle) bundle = self.alter_detail_data_to_serialize(request, bundle) return self.create_response(request, bundle)
使用pdb打断点,发现“/api/v1/author/1/”请求调用get_detail方法,而"/api/v1/author/"请求调用get_list方法,从源码中不难看出,get_detail中调用了cached_obj_get方法,其从cache中拿数据,而get_list调用了obj_get_list方法(源码中有cached_obj_get_list方法,其并未调用),即未从cache中拿数据(其实get_list方法的注释中已经给出了解释
# TODO: Uncached for now. Invalidation that works for everyone may be impossible.),好吧,那解决方式就比较简单了,直接在自己的ModelResource中覆盖掉此方法,更改成:
def get_list(self, request, **kwargs): """ 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). """ # TODO: Uncached for now. Invalidation that works for everyone may be # impossible. base_bundle = self.build_bundle(request=request) objects = self.cached_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() # 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) return self.create_response(request, to_be_serialized)
再次请求"/api/v1/author/"后,发现redis中已经缓存了此结果!
因为对redis的机制不太了解,后面自己将研究一下redis的东西,有什么错误,欢迎大家指正!
本文出自 “7673365” 博客,请务必保留此出处http://7683365.blog.51cto.com/7673365/1675359
标签:django cache tastypie 缓存 redis
原文地址:http://7683365.blog.51cto.com/7673365/1675359