【问题标题】:Get all values from Django QuerySet plus additional fields from a related model从 Django QuerySet 中获取所有值以及来自相关模型的其他字段
【发布时间】:2019-03-11 05:21:39
【问题描述】:

我想知道是否有捷径可以从 Django 模型中获取所有字段,并且只定义通过连接(或多个连接)检索的附加字段。

考虑以下模型:

class A(models.Model):
    text = models.CharField(max_length=10, blank=True)

class B(models.Model):
    a = models.ForeignKey(A, null=True, on_delete=models.CASCADE)
    y = models.PositiveIntegerField(null=True)

现在我可以像这样使用values() 函数了

B.objects.values('y', 'a__text')

获取包含来自B 模型的指定值和来自A 模型的实际字段的元组。如果我只使用

B.objects.values()

我只得到包含来自 B 模型的字段的元组(即,y 和外键 id a)。假设BA 有很多字段,我对属于B 的所有字段感兴趣,但只对A. 中的单个字段感兴趣手动指定values() 中的所有字段名称调用是可能的,但繁琐且容易出错。

那么有没有办法指定我想要所有本地字段,但只需要(少数)特定的连接字段?

注意:我目前使用的是 Django 1.11,但如果解决方案仅适用于更新的版本,我也对此感兴趣。

【问题讨论】:

    标签: python django django-queryset


    【解决方案1】:

    您可以为此使用prefetch_related。见docs

    您想使用延迟等性能优化技术 字段:

    queryset = Pizza.objects.only('name')

    restaurants = Restaurant.objects.prefetch_related(Prefetch('best_pizza', queryset=queryset))

    在你的情况下,你可以这样做:

    from django.db.models import Prefetch
    
    queryset = A.objects.only('text')
    b_list = B.objects.prefetch_related(Prefetch('a', queryset=queryset))
    

    【讨论】:

    • 鉴于 B 属于 A,这种情况是否需要 select_related 而不是 prefetch_related?假设你做 B.objects...
    • @fabio.sussetto prefetch_related 也可以与单个相关对象一起使用。来自文档:Custom prefetching also works with single related relations like forward ForeignKey or OneToOneField. There are a number of cases where prefetching with a custom QuerySet is useful.
    • 我明白了,感谢您的澄清,有点忘了您可以使用 prefetch_related 作为更灵活的 select_related。我想另一个区别是 prefetch_related 你总是会看到一个额外的查询,而 select_related 会在一个查询中使用一个连接。
    【解决方案2】:

    也许这样的事情适用于你的情况?

    B.objects.select_related('a').defer('a__field_to_lazy_load');
    

    这将加载两个模型中的所有字段,除了您在 defer() 中指定的字段,您可以在其中使用通常的 Django 双下划线约定来遍历关系。

    您在 defer() 中指定的字段不会从数据库中加载,但如果您稍后尝试访问它们(例如在模板中),它们将会加载。

    【讨论】:

      猜你喜欢
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 2011-06-16
      • 2019-03-25
      • 2020-02-12
      • 2022-12-01
      • 2021-11-27
      相关资源
      最近更新 更多