python - TypeError 无法 pickle 函数对象(Django 缓存)

标签 python django caching django-orm django-cache

为什么第一个示例抛出 TypeError (can't pickle function objects) 而第二个没有,我想这与 QuerySet 求值 (Django 1.4) 有关吗?

def get_or_set_foo_cache():
    if not cache.get('foo'):
        foo = Foo.objects.annotate(bar_count=Count('bar')).filter(bar_count__gte=1)
        print type(foo) # prints <class 'django.db.models.query.QuerySet'>
        cache.set('foo', foo, 60 * 15)
        return foo
    return cache.get('foo')

示例 2

def get_or_set_foo_cache():
    if not cache.get('foo'):
        foo = Foo.objects.all()
        print type(foo) # prints <class 'django.db.models.query.QuerySet'>
        cache.set('foo', foo, 60 * 15)
        return foo
    return cache.get('foo')

如果我将 foo 设置为列表推导式,它会起作用:

foo = [obj for obj in Foo.objects.annotate(bar_count=Count('bar')).filter(bar_count__gte=1)]

最佳答案

查询集不是结果对象的列表。它是一个延迟评估的对象,当您第一次尝试读取其内容时,它会运行其查询。但是当您从控制台打印它时,它的输出与对象列表相同。所以大多数人认为它们是简单的列表。

在第二个示例中,您将查询集转换为列表。这就是它起作用的原因。你也可以这样做

foo = list(Foo.objects.annotate(bar_count=Count('bar')).filter(bar_count__gte=1))

它也会起作用。

如果您以后不需要它们作为 Foo 对象。我建议使用 values 或 values_list 运算符。这将提供更快的结果和更小的内存占用。 ( http://www.yilmazhuseyin.com/blog/dev/django-orm-performance-tips-part-2/ )

关于python - TypeError 无法 pickle 函数对象(Django 缓存),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12437774/

相关文章:

python - python中的正则表达式组重复

python - 从Python列表列表的内部列表中获取第n个元素

database - Django 中唯一的 BooleanField 值?

mongodb - 缓存 EAV 数据 - XML 或 NoSQL/MongoDB?

asp.net-mvc - 关于高流量网站缓存的问题

python - 为什么在使用 Pandas 的内置绘图调用而不是通过 Matplotlib 绘图时我的日期轴格式被破坏了?

python - 如何在不转换为整数的情况下递归递增二进制数(以列表形式)?

django - Django中QuerySet联合和减法的简单方法?

python - Django:在 Python Shell 中访问管理员用户

caching - 缓存失效算法