1

在 Django 中,在给定模型上,它看起来RelatedManager只能静态设置(参见:docs),但是有没有办法在order_by给定查询集的相关管理器上设置?我尝试使用prefetch_relatedand Prefetch,但这似乎不起作用:

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

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

在这种情况下resFalse

当我尝试访问相关管理器时出现问题:访问 w/oorder_by不会调用另一个 SQL 查询,而如果我再尝试order_by,则会执行一个额外的查询,这会导致一个N + 1SQL 查询被执行。

这两行返回相同的结果,但第一行生成的 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)
4

1 回答 1

2

我在这里聚会有点晚了,但希望我能帮助一些未来的探险家。

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

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

于 2019-01-09T03:42:52.857 回答