Ускорение страницы удаления администратора Django

#python #django #django-admin #django-orm

#python #django #django-администратор #django-orm

Вопрос:

Как бы вы ускорили действие / страницу удаления записи администратора Django?

У меня есть модель B с ограничением внешнего ключа для модели A. Для каждой записи в A существует около 10 тысяч записей в B, привязанных к A. Поэтому, когда мне нужно удалить запись в A, используя действие «Удалить выбранное A» по умолчанию в admin, Django потребуется 15 минут, чтобы запросить и отобразить каждую удаляемую запись в B. Как бы мне изменить это, чтобы вместо перечисления тысяч зависимых объектов отображалось только количество удаляемых зависимых объектов?

Ответ №1:

Как обычно, просмотрите исходный код 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 /

В основном действие.в настоящее время py работает путем формирования соответствующего набора запросов, вызывая delete() непосредственно набор запросов, но не группируя его в единую транзакцию БД. Выполняя простые временные тесты в образце базы данных sqlite, я обнаружил, что удаление ~ 150 объектов без транзакций заняло 11,3 секунды при использовании qs.delete() и 13,4 секунды при использовании for obj in qs: obj.delete() . При использовании транзакций ( @transaction.commit_on_success перед функциями удаления) выполнение одних и тех же команд занимало всего 0,35 секунды и 0,39 секунды (примерно в 30 раз быстрее). Предоставленное использование транзакций может временно заблокировать базу данных, что может быть неприемлемым вариантом.

Чтобы разумно расширить возможности администратора django (обычно вы не хотели бы редактировать исходный код напрямую; особенно если другие пользователи используют те же файлы или если вы, возможно, захотите вернуться позже или используете другие сайты django на том же компьютере), смотрите: http://www.djangobook.com/en/1.0/chapter17/#cn35

Комментарии:

1. Это поможет, но другая большая проблема связана с django.contrib.admin.actions. py, где выполняется вызов get_deleted_objects (строка 34 в django 1.4). Здесь компилируется полная иерархия объектов для последующего отображения в шаблоне. По крайней мере, здесь зависал мой код. Надеюсь, это также поможет.

Ответ №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 %}