在Django中的相关字段上指定order_by

时间:2016-02-05 06:50:13

标签: django django-queryset django-orm django-select-related

在Django中,在给定模型上看起来RelatedManager可能只能静态设置(see: docs),但有没有办法在相关管理器上设置order_by给出Queryset?我尝试使用prefetch_relatedPrefetch,但这似乎不起作用:

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

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

在这种情况下,resFalse

当我尝试访问相关管理器时出现问题:访问w / o 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)

1 个答案:

答案 0 :(得分:1)

我在这里参加聚会有点晚了,但希望我能为将来的探险家提供帮助。

我遇到了一个非常相似的问题,甚至发现了一个旧的错误报告,该报告或多或少与该here相关,并且据此判断,它不会很快得到解决;如果该页面的最后几行是正确的,则将永远无法解决。因此,您根本无法按相关字段排序,也无法检索重复项;无论是您尝试过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 

对我来说,这确实足够好,尽管它确实存在明显的缺点,即始终以这种方式进行排序。如果有人可以,我很想知道一种更好的方法。