tastypie使用cache对list data无效问题

这就算是第一篇博客了,我老大陈如杰(一个牛逼的程序员)讲过,只有自己研究了的东西才能写到博客上,我谨遵教诲。

环境: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的东西,有什么错误,欢迎大家指正!

时间: 2025-01-04 16:57:59

tastypie使用cache对list data无效问题的相关文章

jQuery对象数据缓存Cache原理及jQuery.data详解

网上有很多教你怎么使用jQuery.data(..)来实现数据缓存,但有两个用户经常使用的data([key],[value])和jQuery.data(element,[key],[value])几乎没有什么文章说清楚它们两的区别,所以我用到了,研究下分享给大家.$("").data([key],[value])与jQuery.data(element,[key],[value])的区别这两个函数都是用来在元素上存放数据也就平时所说的数据缓存,都返回jQuery对象,当时我分别在使用

缓存与缓冲的区别 Difference Between Cache and Buffer

Cache vs Buffer Both cache and buffer are temporary storage areas but they differ in many ways. The buffer is mainly  found in ram and acts as an area where the CPU can store data temporarily, for example, data meant for other output devices mainly w

浅谈数据库系统中的cache(转)

http://www.cnblogs.com/benshan/archive/2013/05/26/3099719.html 浅谈数据库系统中的cache(转) Cache和Buffer是两个不同的概念,简单的说,Cache是加速"读",而buffer是缓冲"写",前者解决读的问题,保存从磁盘上读出 的数据,后者是解决写的问题,保存即将要写入到磁盘上的数据.在很多情况下,这两个名词并没有严格区分,常常把读写混合类型称为buffer cache,本文后续的论述中,统一

jQuery.data的是jQuery的数据缓存系统

jQuery.Data源码 jQuery.data的是jQuery的数据缓存系统.它的主要作用就是为普通对象或者DOM元素添加数据. 1 内部存储原理 这个原理很简单,原本要添加在DOM元素本身的数据,现在被集中的存储在cache集合中.它们之间靠一个从1开始的数字键来联系着.这样DOM元素就不会像以前那么笨重了,更不会出现以前那种循环引用而引起的内存泄漏.现在DOM只需要保存好这个数字键值即可.这个属性值被保存在DOM元素的一个属性里,该属性名是由jQuery.expando生成的. 2 Da

JQuery data API实现代码分析

JQuery data 接口是什么? .data() Store arbitrary data associated with the matched elements or return the value at the named data store for the first element in the set of matched elements. 根据jquery官网介绍,data给存储DOM关联的数据, 设置数据是对$选取的所有JQuery对象, 获取数据是对$选取的所有对象的

浅谈数据库系统中的cache

Cache和Buffer是两个不同的概念,简单的说,Cache是加速“读”,而buffer是缓冲“写”,前者解决读的问题,保存从磁盘上读出的数据,后者是解决写的问题,保存即将要写入到磁盘上的数据.在很多情况下,这两个名词并没有严格区分,常常把读写混合类型称为buffer cache,本文后续的论述中,统一称为cache. Oracle中的log buffer是解决redo写入的问题,而data buffer cache则解决data block的读写问题.对于Oracle来说,如果IO没有在SG

Distributed Cache Coherence at Scalable Requestor Filter Pipes that Accumulate Invalidation Acknowledgements from other Requestor Filter Pipes Using Ordering Messages from Central Snoop Tag

A multi-processor, multi-cache system has filter pipes that store entries for request messages sent to a central coherency controller. The central coherency controller orders requests from filter pipes using coherency rules but does not track complet

Parallelized coherent read and writeback transaction processing system for use in a packet switched cache coherent multiprocessor system

A multiprocessor computer system is provided having a multiplicity of sub-systems and a main memory coupled to a system controller. An interconnect module, interconnects the main memory and sub-systems in accordance with interconnect control signals

Data analysis system

A data analysis system, particularly, a system capable of efficiently analyzing big data is provided. The data analysis system includes an analyst server, at least one data storage unit, a client terminal independent of the analyst server, and a cach