#python #django #django-admin
#python #django #django-admin
Вопрос:
Этот сценарий происходит слишком часто в моем проекте:
- кто-то добавляет модель
Foo
с несколькимиForeignKey
полями, одно из которых ссылается на modelBar
- для этой модели добавлен администратор (и работает нормально)
- код развернут
- на рабочем сервере,
Bar
имеет миллионы экземпляров - кто
Foo
-то обращается к странице администратора; Django пытается получить всеBar
s сразу (чтобы отобразить их в поле со списком), и сервер перегружается - позже проблема будет устранена путем редактирования
Foo
admin и добавленияbar
вraw_id_fields
.
Я бы хотел предотвратить повторение этой ситуации в будущем, желательно каким-то образом указав (раз и навсегда), что Bar
у него много строк, и его всегда следует обрабатывать так, как если бы поле, ссылающееся на него, было указано raw_id_fields
на всех страницах администратора. Возможно ли это как-то?
Ответ №1:
Это отличный момент. Это критическая проблема, которая может отключить базу данных и даже веб-сервер.
Учитывая это, я считаю, что подход по умолчанию ДОЛЖЕН быть raw_id_fields
правильным. Если вы знаете, что делаете, тогда вы меняете это поведение.
К сожалению, большинство авторов библиотек интерфейсов администратора не согласны с этой мыслью. Не только для Python-Django, но и для других сообществ, таких как Ruby-Rails.
5 лет назад мне надоела одна и та же проблема, тогда я разработал django-smart-autoregister, который делает это, а также автоматически настраивает, используя другие хорошие шаблоны. Даже сегодня я сталкиваюсь с этой проблемой, поэтому, я думаю, стоит взглянуть.
ps: библиотека изначально была реализована с использованием модульного подхода, хотя вы просто вызываете некоторые функции, которые настраивают raw_id_fields
для вас в соответствии с полем модели.
Ответ №2:
Из документов:
ForeignKey представлен django.forms .ModelChoiceField, которое является полем выбора, выбор которого является набором запросов модели.
ModelChoiceField расширяет поле и поэтому имеет свойство виджета, которым можно злоупотреблять https://github.com/django/django/blob/master/django/forms/fields.py#L49
Добавьте это где-нибудь в файлы вашего проекта.
from django.forms import ModelChoiceField
from django.contrib.admin.widgets import ForeignKeyRawIdWidget
ModelChoiceField.widget = ForeignKeyRawIdWidget
недостаток: это также произойдет в формах, не являющихся администраторами
Комментарии:
1. Хм, это хорошая отправная точка — теперь, возможно, можно заставить ModelAdmin выборочно использовать этот виджет при создании его ModelForm.