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/

Другие вопросы по тегам