Django: ограничить модели
У меня есть модель заказа:
class Order(models.Model):
profile = models.ForeignKey(Profile, null=True, blank=True)
Который возвращает все возможные профили для заказа, который не является необходимым и замедляет загрузку страницы заказа администратора.
Я хочу, чтобы возвращаемый профиль был просто тем пользователем, который разместил заказ. Я попытался изменить его на:
class Order(models.Model):
profile = models.ForeignKey(Profile, null=True, blank=True, limit_choices_to={'order': 99999})
который возвращает правильный профиль для номера заказа 99999, но как я могу получить это динамически. Модель заказа не знает о себе, но номер заказа содержится в URL.
Каков наилучший способ сделать это?
3 ответа
Я еще раз взглянул на это, и это, кажется, работает, хотя это похоже на хак! Проблема заключалась в том, что номер заказа, по-видимому, не существует в запросе, поэтому я анализирую запрошенный URL. Я положил это в мой заказ администратора:
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "profile":
try:
order = int(filter(str.isdigit, str(request.path_info)))
except:
order = request.GET.get('order')
kwargs["queryset"] = Profile.objects.filter(order=order)
return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
Строка, которая фильтрует строку URL для целого числа, работает для страницы заказа на изменение администратора, но не работает для обзора страницы заказа, поэтому я добавил попробовать / исключая. Любые предложения / улучшения приветствуются!
Я полагаю из контекста, который вы имеете в виду на дисплее на странице администратора Django. Если вы установите raw_id_fields = {'my_foreign_key'}
Вы получите номер, текстовое описание связанной модели (от str) и красивое всплывающее окно, чтобы открыть экземпляр страницы администратора для связанных моделей.
В качестве альтернативы вы можете использовать list_select_related = True, чтобы получить то же поведение, что и сейчас, но на несколько порядков меньше количество запросов.
Если вы используете Django Admin, вы можете переопределить метод formfield_for_foreignkey
на ваше ModelAdmin
класс для динамического изменения набора запросов для поля профиля, например, на основе параметра GET (поскольку у вас есть доступ к request
внутри метода.
Посмотрите на этот пример из документации (адаптированной для вашего случая):
class MyModelAdmin(admin.ModelAdmin):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "profile":
# You can get the order number from the GET parameter:
# order = request.GET.get('order')
# or a fixed number:
order = '12345'
kwargs["queryset"] = Profile.objects.filter(order=order)
return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
Ссылка в документации: https://docs.djangoproject.com/en/1.9/ref/contrib/admin/