【问题标题】:Get specific field of model in select_related在 select_related 中获取模型的特定字段
【发布时间】:2021-12-23 21:46:34
【问题描述】:

我的项目中有一个查询:

qs = self.model.objects \
            .filter(user=self.request.user, pk__iexact=pk) \
            .select_related('shipping_addr', 'billing_addr', 'cart') \
            .first()

我想进一步优化这个查询。 我只想获取 shipping_addr 的“id”和“name”字段。 但这不起作用:

qs = self.model.objects \
                .filter(user=self.request.user, pk__iexact=pk) \
                .select_related('shipping_addr', 'billing_addr', 'cart') \
                .only('shipping_addr__name','shipping_addr__id') \
                .first()

我知道这段代码没有运行的原因,我不知道我该怎么办????。

【问题讨论】:

  • 为什么要获取三个相关模型,而您只需要一个?为什么要使用双下划线?这些不适用于选择字段。您也可以只使用 pk=pk。
  • 1:这只是一个示例。不是我想做的所有事情。 “简单胜于复杂”_____2:是的,没错。也许最好使用 pk=pk.____ 你对主要问题有什么想法吗?
  • 我已经在下面回答了。我认为您问题中的查询没有多大意义。不需要first()filter(),因为你得到一个对象是因为 pk。您也不需要获取其他两个模型,因为之后您不再使用它们。因此,它只是一个对象,而不是与一个相关对象一起获取的查询集。然后就像我在答案中显示的那样获取您的相关字段。我认为不需要进一步优化。

标签: django django-models optimization django-orm


【解决方案1】:

select_related() 仅限于单值关系——外键和一对一。见:https://docs.djangoproject.com/en/3.1/ref/models/querysets/#select-related

所以它需要从具有外键的模型开始,然后您也可以选择要获取的相关父对象。所以你的self.model 有一个指向shipping_addr 的外键。

您希望通过保存额外的数据库命中来检索shipping_addr.name,因为

object=self.model.objects.get(pk=pk)
shipping_address_name=object.shipping_addr.name

两次击中您的数据库。因此,您可以这样做:

object=self.model.objects.select_related('shipping_addr').get(pk=pk)
shipping_address_name = object.shipping_addr.name

这样你就消除了一次数据库命中,因为你的对象将从已经包括shipping_addr的数据库中获取。

除非您的shipping_addr 有很多字段或检索起来非常昂贵,否则我不会费心使用only(),但如果您坚持可以添加它。没有看到你的模型很难说。

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 2016-06-26
    • 2016-06-02
    • 2015-04-06
    • 2021-12-29
    • 2014-02-06
    • 2011-04-08
    • 2020-12-17
    • 1970-01-01
    相关资源
    最近更新 更多