Указание order_by в связанном поле в Django

В Django для данной модели похоже, что RelatedManager может быть установлен только статически (см. документы), но есть ли способ установить order_by в связанном менеджере для данного набора запросов? Я пытался использовать prefetch_related и Prefetch, но это не работает:

qs = qs.prefetch_related(
   Prefetch('item_set', queryset=Item.objects.order_by('capture_dt').all()))

res = qs.first().item_set.all().ordered

В данном случае res равно False.

Проблема возникает, когда я пытаюсь получить доступ к соответствующему менеджеру: доступ без order_by не вызывает другого SQL-запроса, тогда как если я затем пытаюсь order_by, выполняется дополнительный запрос, который вызывает выполнение N + 1 SQL-запросов.

Эти две строки возвращают одинаковые результаты, но первая генерирует гораздо меньше SQL-запросов:

r0 = [x.pk for x in sorted(self.parent.item_set.all(), key=lambda s: s.capture_dt)].index(self.pk)
r1 = list(x.pk for x in self.parent.item_set.order_by('capture_dt').all()).index(self.pk)

person Alex Rothberg    schedule 05.02.2016    source источник
comment
без моделей сложно сказать, вы ищете .order_by('fkmodel__field')?..   -  person Sayse    schedule 05.02.2016
comment
Я не хочу заказывать набор запросов верхнего уровня (выше этого будет qs). Я просто хочу упорядочить элементы в item_set для каждой записи в qs.   -  person Alex Rothberg    schedule 05.02.2016


Ответы (1)


Я немного опоздал на вечеринку, но, надеюсь, смогу помочь какому-нибудь будущему исследователю.

У меня была очень похожая проблема, и я даже нашел старый отчет об ошибке, который более или менее относится к этому здесь, и судя по всему, решить ее в ближайшее время не удастся; и если последние строки на этой странице верны, она никогда не будет решена. Таким образом, вы просто не можете упорядочить по связанному полю и не получить дубликаты; будь то способ, которым вы пытались использовать RelatedManger или какой-либо другой подход: например, SomeModel.objects.order_by('related__related_field')

Я нашел способ заставить его работать, хотя он и не элегантный. В моем случае у меня есть модель, которая описывает базовую модель гитары, которую я собираю, и есть фотографии, связанные с этой моделью. Я хотел бы, чтобы запрос упорядочивал фотографии на основе уровня приоритета; это позволяет мне контролировать порядок отображения фотографий на веб-сайте, обслуживаемом серверной частью Django. Таким образом, порядок жестко запрограммирован в модели следующим образом:

class PhotosModel(models.Model):
    class Meta:
        ordering = ['priority_level']
    priority_level = models.SmallIntegerField()
    photo_src = models.URLField(null=True, blank=True, default=None, max_length=65)
    photo_name = models.CharField(max_length=20)
    photo_description = models.TextField(max_length=200, blank=True, null=True)
    base_model = models.ForeignKey(BaseModelModel,
                                   on_delete=models.CASCADE,
                                   related_name='photos')

    def __str__(self):
        return self.photo_name 

Для меня это работает достаточно хорошо, хотя у него есть очевидный недостаток, что он всегда упорядочен таким образом. Я хотел бы знать лучший способ, если у кого-то есть.

person Hildy    schedule 09.01.2019