Speed up Django admin by cache
由于之前从来没有遇到过类似的业务需求,所以一直没觉得Django自带的后台管理系统admin有什么问题,
最近在做一个中小学题目管理系统,上来就是百万级别的题目,结果在admin中,打开题目的列表查看第一页
的十来个数据居然需要十几秒,简直是慢的令人发指,用django-debug-toolbar
查看了一下,居然是因为求总页数时的select count(*) from soma_table;
导致的,
这个数据其实没什么大用,就是计算一下总共有几万页而已,具体是6847321还是6847322其中并不重要,
在网上简单查找了一下,找到了一个通过利用mysql自带的估计表中的数据的方法来完成这一操作的,
然后我根据自己的业务逻辑,对上文中的方法进行了一些修改,结合Django自带的缓存系统,
使得我的页数是精确值,但是又可以在很大程度上提升速度。代码见下:
首先需要在settings.py
中启用缓存:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
}
}
然后在models.py
中自定义Manager
以及相关的覆盖方法如下:
from django.core.cache import cache
from django.db.models.query import QuerySet
from django.db import models
class CacheCount(QuerySet):
def count(self):
cache_key = 'admin_total_count' # change this accordingly
_count = cache.get(cache_key)
if _count:
return _count
count = self.query.get_count(using=self.db)
cache.set(cache_key, count, 3600 * 24)
return count
class CacheCountManager(models.Manager):
def get_query_set(self, using=None):
# 这里需要注意,因为我使用了多个数据库,所以这里需要制定具体的数据库,
# 这里你的具体代码可能需要一些变动
return CacheCount(self.model, using=using)
class YourModel(model.Model):
...
objects = CacheCountManager()
接下来就是在admin.py
中覆盖get_queryset
方法:
from django.contrib import admin
from app.models import YourModel
# Register your models here.
class YourModelModelAdmin(admin.ModelAdmin):
# A handy constant for the name of the alternate database.
using = 'the_db'
def view_on_site(self, obj):
return obj.url
def save_model(self, request, obj, form, change):
obj.save(using=self.using)
def delete_model(self, request, obj):
obj.delete(using=self.using)
# Here is the code
def get_queryset(self, request):
qs = self.model.objects.get_query_set(using=self.using)
ordering = self.ordering or ()
if ordering:
qs = qs.order_by(*ordering)
return qs
admin.site.register(YourModel, YourModelModelAdmin)
至此,再次打开admin的列表页,就只有第一次会像平时一样慢,但是之后就全部都是秒开了。
blog comments powered by Disqus