使用子列更新 Django 中的列

Posted

技术标签:

【中文标题】使用子列更新 Django 中的列【英文标题】:Update column in Django with child columns 【发布时间】:2021-09-19 08:06:08 【问题描述】:

我有两个模型ParentChild

class Parent(models.Model):
    id = Base64UUIDField(primary_key=True, editable=False)
    cost = models.DateTimeField(default=None, blank=True, null=True)

class Child(models.Model):
    id = Base64UUIDField(primary_key=True, editable=False)
    cost = models.DateTimeField(default=None, blank=True, null=True)
    parent = models.ForeignKey(Parent, related_name= "children", related_query_name= "child")

我需要将Parent 对象的cost 列填充为该父级所有子级的最大成本

我试图注释到一个新列new_cost,以及它的作品。

parents.annotate(new_cost=Max('child__cost'))

但我需要将值填充到现有列 cost。尝试过类似的方法,但不起作用。

parents.update(cost=Max('child__cost'))

【问题讨论】:

我不确定您是否应该在Parent 中有一个cost 字段,通常最好在需要时对其进行注释。 【参考方案1】:

可能这可以通过Subquery expression 实现:

from django.db.models import OuterRef, Subquery

Parent.objects.update(
    cost=Subquery(Child.objects.filter(
        parent_id=OuterRef('pk')
    ).values('cost').order_by('-cost')[:1])
)

但是,当您需要相关 Childs 的最大成本时,我建议您直接使用 .annotate(…)

【讨论】:

【参考方案2】:

使用aggregate 反对annotate

test = parents.aggregate(new_cost=Max('child__cost'))
parents.update(cost=test["new_cost"])

【讨论】:

这将为 all Parents 和 cost 设置为所有 Parents 的所有孩子的最大值,可能 OP 想要设置这个 per Parent. AttributeError: 'dict' 对象没有属性 'aggregate'。 gettig 这个错误 @PARRE PRITHVI 我认为@Willem Van Onsem 是正确的,将cost 用于两个模型并不是最佳实践。您可以在父模型中使用注释或@propety 成本跨度> 但如果你想这样做,请展示你如何获得parents

以上是关于使用子列更新 Django 中的列的主要内容,如果未能解决你的问题,请参考以下文章

使用 plpgsql 更新函数中的列

使用过程更新表中的列

如何使用不相关表中的列数据更新列 - MySQL

如何使用数组值更新数据库中的列?

使用集合中的值更新表中的列

使用内部联接更新多个表中的列