加速Django管理后台删除页面

6

如何加速Django Admin记录删除操作/页面?

我有一个模型B,它与模型A有外键约束。对于A中的每条记录,都有约10k条记录绑定到A的B。因此,当我使用默认的"删除所选A"操作在管理界面中删除A中的一条记录时,Django将花费15分钟来查询和显示正在被删除的每个B记录。我该如何修改它,使其只显示正在被删除的相关对象数量,而不是列出数千个相关对象?

2个回答

10

像往常一样,浏览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()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


这会有所帮助,但另一个大问题在于 django.contrib.admin.actions.py 中调用 get_deleted_objects 的地方(django 1.4 中的第34行)。在此处,完整的对象层次结构将被编译以供稍后在模板中显示。至少我的代码就是在这里卡住了。希望这也能有所帮助。 - Rob

1
对于 Django 1.4,@drjimbob 的配方略有不同:
更新文件:
django/contrib/admin/templates/admin/delete_selected_confirmation.html

在第35行替换,保留HTML。
{% for deletable_object in deletable_objects %}
    <ul>{{ deletable_object|unordered_list }}</ul>
{% endfor %}

for

{% 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 %} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接