使用Django 1.11,Python 3.6
我没有任何运气。我正在尝试优化一个缓慢的Django Admin页面,由于大量select
下拉列表和多个内联,这个页面会产生大量重复的SQL查询。
我已尝试使用cacheops
库和Redis商店,但根本没有任何内容被缓存,即使我将所有设置为使用'*.*': {'ops': 'all', 'timeout': 60*60},
自动缓存。我假设这可能是因为Admin似乎绕过了正常的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查询!我怎么阻止它这样做?
答案 0 :(得分:0)
在cacheops中禁用了admin中的自动缓存。 here对此进行了解释:
哦,管理员明确禁用了缓存。
这是历史决定,我想知道是否应该在下一个主要版本中将其关闭,但目前情况仍然如此。要缓存管理员,您需要覆盖
.get_queryset()
方法并自己在queryset上调用.cache()
。
虽然不确定如何形成各种选择的查询集。