开发者

Speeding Up the Django Admin Delete Page

开发者 https://www.devze.com 2023-03-04 12:11 出处:网络
How would you speed up the Django Admin record deletion action/page? I have a model B with a foreign key constraint to model A. For every record in A, there are about 10k records in B bound to A. So

How would you speed up the Django Admin record deletion action/page?

I have a model B with a foreign key constraint to model A. For every record in A, there are about 10k records in B bound to A. So when I have to delete a record in A using the default "Delete selected A" action in admin, Django will take 15 minutes to query and display every record being deleted in B. How would I modify this so instead of listing thousands of dependent objects, it only displays a coun开发者_高级运维t of the dependent objects being deleted?


As usual browse the django source to find your answer (it's surprisingly readable with variables, functions, classes, and files named logically).

Looking at django/contrib/admin/templates/admin/delete_confirmation.html (in django 1.2.5), you will see a template that has the 24th line contains:

<ul>{{ deleted_objects|unordered_list }}</ul>

If you change this to say

<p>{{ deleted_objects|count }} objects</p>

or

{% if 100 < deleted_objects|count %}
    <p>{{ deleted_objects|count }} objects</p>
{% else %}
    <ul>{{ deleted_objects|unordered_list }}</ul>
{% endif %}

it will only display the count of deleted objects (if there are many deleted objects).

You may also want to experiment with editing django/contrib/admin/templates/admin/actions.py to use a SQL transaction to do the mass deletion more quickly. See: http://docs.djangoproject.com/en/dev/topics/db/transactions/

Basically action.py currently works by forming the appropriate queryset, calling delete() directly the queryset, but not grouping it into a single db transaction. Doing simple time tests on a sample sqlite database I found that deleting ~150 objects without transactions took 11.3 seconds using qs.delete() and 13.4 seconds using for obj in qs: obj.delete(). Using transactions (@transaction.commit_on_success before the deleting functions), the same commands took only 0.35 seconds and 0.39 seconds (about 30 times faster). Granted using transactions may lock the database temporarily, which may not be an acceptable option.

To extend the django admin sensibly (normally you wouldn't want to edit the source directly; especially if other users are using the same files or if you may ever want to revert back later or are running other django sites on the same machine) see: http://www.djangobook.com/en/1.0/chapter17/#cn35


For Django 1.4 @drjimbob's recipe is slightly different:

Update the file:

django/contrib/admin/templates/admin/delete_selected_confirmation.html

and on line 35 replace

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

精彩评论

暂无评论...
验证码 换一张
取 消