加快Django后台删除页面速度
如何加快Django后台删除记录的速度?
我有一个模型B,它和模型A有外键关系。也就是说,模型A中的每一条记录大约都有1万条记录在模型B中与之关联。所以当我在后台使用默认的“删除选中的A”操作来删除A中的一条记录时,Django需要花15分钟来查询并显示所有要删除的B中的记录。有没有办法修改这个过程,让它只显示要删除的关联记录的数量,而不是列出成千上万的记录?
2 个回答
对于Django 1.4版本,@drjimbob提供的做法稍微有点不同:
更新这个文件:
django/contrib/admin/templates/admin/delete_selected_confirmation.html
然后在第35行,把
{% for deletable_object in deletable_objects %}
<ul>{{ deletable_object|unordered_list }}</ul>
{% endfor %}
替换成
{% for deletable_object in deletable_objects %}
{% if 100 < deletable_object|length %}
<p>{{ deletable_object|length }} objects</p>
{% else %}
<ul>{{ deletable_object|unordered_list }}</ul>
{% endif %}
{% endfor %}
像往常一样,可以查看Django的源代码来找到你的答案(其实它的代码很容易读懂,变量、函数、类和文件的命名都很有逻辑)。
看一下 django/contrib/admin/templates/admin/delete_confirmation.html
(在Django 1.2.5版本中),你会发现第24行包含了:
<ul>{{ deleted_objects|unordered_list }}</ul>
如果你把它改成
<p>{{ deleted_objects|count }} objects</p>
或者
{% if 100 < deleted_objects|count %}
<p>{{ deleted_objects|count }} objects</p>
{% else %}
<ul>{{ deleted_objects|unordered_list }}</ul>
{% endif %}
这样的话,它只会显示被删除对象的数量(如果删除的对象很多的话)。
你可能还想试着编辑 django/contrib/admin/templates/admin/actions.py
,使用SQL事务来更快地进行批量删除。可以参考这个链接:http://docs.djangoproject.com/en/dev/topics/db/transactions/
简单来说,action.py现在的工作方式是形成一个合适的查询集,然后直接调用delete()来删除这些对象,但没有把这些操作放在一个数据库事务中。通过在一个示例的sqlite数据库上做简单的时间测试,我发现不使用事务删除大约150个对象需要11.3秒,使用 qs.delete()
是13.4秒,而使用 for obj in qs: obj.delete()
则是13.4秒。使用事务(在删除函数前加上 @transaction.commit_on_success
),同样的命令只需要0.35秒和0.39秒(快了大约30倍)。当然,使用事务可能会暂时锁定数据库,这可能不是一个可接受的选择。
如果想合理地扩展Django的管理界面(通常你不想直接编辑源代码;特别是当其他用户也在使用相同的文件,或者你可能想以后恢复原样,或者在同一台机器上运行其他Django网站时),可以查看这个链接:http://www.djangobook.com/en/1.0/chapter17/#cn35