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