【问题标题】:How to get Django Admin to cache select options on inlines?如何让 Django Admin 缓存内联的选择选项?
【发布时间】:2018-11-13 20:12:05
【问题描述】:

使用 Django 1.11、Python 3.6

我对此一点运气都没有。我正在尝试优化一个缓慢的 Django 管理页面,由于大量 select 下拉列表和多个内联,该页面会产生大量重复的 SQL 查询。

我尝试过使用 cacheops 库和 Redis 存储,但根本没有缓存任何内容,即使我将 everything 设置为使用 '*.*': {'ops': 'all', 'timeout': 60*60}, 自动缓存也是如此。我假设这可能是因为管理员似乎绕过了正常的 Django ORM 对象。

说到这里,我尝试实现一个定制的对象管理器,它使用cachetools 库的 TTLCache 类进行缓存:

from django.db import models
from cachetools import TTLCache, cached

cache = TTLCache(maxsize=100, ttl=3600)

class CacheManager(models.Manager):
    @cached(cache)
    def get(self, *args, **kwargs):
        print("Caching get. args: %r. kwargs: %r" % (args, kwargs))
        return super(CacheManager, self).get(*args, **kwargs)

    @cached(cache)
    def all(self, *args, **kwargs):
        print("Caching all. args: %r. kwargs: %r" % (args, kwargs))
        return super(CacheManager, self).all(*args, **kwargs)

    @cached(cache)
    def filter(self, *args, **kwargs):
        print("Caching filter. args: %r. kwargs: %r" % (args, kwargs))
        return super(CacheManager, self).filter(*args, **kwargs)

    @cached(cache)
    def order_by(self, *args, **kwargs):
        print("Caching order_by. args: %r. kwargs: %r" % (args, kwargs))
        value = super(CacheManager, self).order_by(*args, **kwargs)
        print(value)
        return value

    @cached(cache)
    def first(self, *args, **kwargs):
        print("Caching first. args: %r. kwargs: %r" % (args, kwargs))
        return super(CacheManager, self).first(*args, **kwargs)

然后是我的模型类:

class Role(models.Model):
    date_added = models.DateTimeField(auto_now_add=True)
    date_modified = models.DateTimeField(auto_now=True)
    name = models.CharField(max_length=100, unique=True)

    objects = CacheManager()

    class Admin:
        manager = CacheManager()

这也没有任何作用。起初我认为这是由于管理员没有使用定制的对象管理器,但我在 StackOverflow 上发现了一条评论,认为使用管理器添加 Admin 类应该可以解决这个问题 - 但在这种情况下显然不是,因为加载时具有角色select 的管理页面我在日志中得到了这个:

2018-06-04 11:49:06,350 [DEBUG] django.db.backends: (0.003) QUERY = 'SELECT [cms_role].[id], [cms_role].[date_added], [cms_role].[ date_modified], [cms_role].[name] FROM [cms_role] ORDER BY [cms_role].[name] ASC' - PARAMS = (); args=()

** 跳过了 20 次以上的重复 **

2018-06-04 11:49:07,572 [DEBUG] django.db.backends: (0.002) QUERY = 'SELECT [cms_role].[id], [cms_role].[date_added], [cms_role].[ date_modified], [cms_role].[name] FROM [cms_role] ORDER BY [cms_role].[name] ASC' - PARAMS = (); args=()

超过一秒的重复 SQL 查询!我该如何阻止它这样做??

【问题讨论】:

  • 我正在考虑使用 CacheManager,这不起作用,因为它实际上正在缓存当时可能尚未执行的查询集,所以我没有缓存结果。
  • 我还确认 Cacheops 正在缓存常规查询,即在管理页面之外。这只是管理员的问题。
  • 模型中的class Admin 是什么?据我所知,它什么也没做,管理员是另一种方式构建的。

标签: python django python-3.x


【解决方案1】:

在 cacheops 中禁用了管理中的自动缓存。这是解释here

哦,缓存在管理员中被明确禁用。

这是历史决定,我想知道是否应该在下一个主要版本中将其关闭,但现在它保持这种状态。要在管理员中缓存,您需要自己覆盖 .get_queryset() 方法并在查询集上调用 .cache()

但不确定各种选择的查询集是如何形成的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 2011-08-27
    • 2011-10-22
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 2018-03-31
    相关资源
    最近更新 更多