Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Speeding Up the Django Admin Delete Page

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 count of the dependent objects being deleted?

like image 623
Cerin Avatar asked May 06 '11 21:05

Cerin


People also ask

Why Django admin is slow?

Custom Filterings. This is an extra alert to check custom filtering functions ( list_filter ) in Django admin that you might implement previously. In my case, there was a field which used to get distinct values across all documents. It extremely slows down the performance as the number of documents increases.

How can I remove extra's from Django admin panel?

You can add another class called Meta in your model to specify plural display name. For example, if the model's name is Category , the admin displays Categorys , but by adding the Meta class, we can change it to Categories . Literally saved my life!

Can we customize Django admin panel?

The Django admin is a powerful built-in tool giving you the ability to create, update, and delete objects in your database using a web interface. You can customize the Django admin to do almost anything you want.


1 Answers

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

like image 58
dr jimbob Avatar answered Sep 21 '22 21:09

dr jimbob