Django 基于其他模型更新模型字段

Django update model field based on other model

我有两个模型。

class A(models.Model):
    count = models.PositiveIntegerField(default=0)

class B(models.Model):
    a = models.ForeignKey(A, related_name='a_b')
    some_boolean = models.BooleanField(default=False)

现在我想按以下方式为所有 A 个对象设置 A.count

A.count = (Number of B's for A with some_boolean=True) * 10
         + Number of B's for A with some_boolean=False

我尝试了以下方法:

all = A.objects.prefetch_related('bs').all()
for a in all:
    # Modify object
    # Save object

但这非常低效。关于如何进行的任何建议。

在一个你说你

have about 10 million A objects and each A object has upto 100 B objects. So it will take a lot of time.

这意味着有很多工作要做,但这并不一定意味着您的方法执行该工作效率低下。是不是把时间或记忆花在了不必要的事情上?

可能是:根据您更新和保存单个 A 对象的方式,.prefetch_related('bs') 可能不会给您带来任何优势。预取对象肯定会占用内存 space,在您的情况下会占用大量内存,因为它们的数量庞大:最多 10 9 B 个对象。而且您不需要那些 B 对象的内容,只需要它们的数量取决于内容。但这可以通过 QuerySets 像这样计算:

for a in A.objects.all():
    bs = a.a_b
    a.count = (bs.filter(some_boolean=True).count() * 10
        + bs.filter(some_boolean=False).count())
    a.save()

像这样,B table 条目永远不会创建为此代码的 python 对象。相应的计数由底层数据库计算,通常应该更有效。

更有效的方法可能是让数据库也对 A 对象进行迭代,并一次性更新它们。 QuerySet's update method 浮现在脑海中,但在文档中,我看不到如何使用它来更新具有条目特定值的条目,正如我们在这里需要的那样。所以我想这对于 django 的 ORM 是不可能的。

如果您愿意使用 django 的 ORM,为此目的用 sqlalchemy 或类似的东西制作一个 SQL UPDATE 语句可能并不难。