【问题标题】:Specifying order_by on Related Field in Django在 Django 中的相关字段上指定 order_by
【发布时间】:2016-05-15 01:32:23
【问题描述】:

在 Django 中,在给定模型上,RelatedManager 看起来只能静态设置 (see: docs),但有没有办法在给定查询集的相关管理器上设置 order_by?我尝试使用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)

【问题讨论】:

  • 没有模型很难说,你在找.order_by('fkmodel__field')?..
  • 我不想订购顶级查询集(上面是qs)。我只想为qs 中的每个条目订购item_set 中的项目。

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


【解决方案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 

对我来说,这已经足够好用了,尽管它确实有一个明显的缺点,那就是它总是以这种方式排序。我很想知道一种更好的方法,如果有人有的话。

【讨论】:

    猜你喜欢
    • 2017-06-09
    • 2016-10-19
    • 2017-11-24
    • 2011-03-10
    • 2011-01-11
    • 2022-09-28
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多