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

时间:2016-02-27 13:42:52

标签: python django django-queryset django-orm

我有两个模特。

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.count个对象设置A

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

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

1 个答案:

答案 0 :(得分:0)

comment你说你

  

有大约1000万个A个对象,每个A个对象最多有100个B个对象。所以这需要很多时间。

这意味着有很多工作,但这并不一定意味着您的方法无法有效地执行该工作。是否花费时间或记忆在不必要的事情上?

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

B

像这样,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() 表条目永远不会被创建为此代码的python对象。相应的计数由底层数据库计算,通常应该显着提高效率。

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

如果您愿意解决django的ORM问题,那么使用A或类似的东西制作一个SQL UPDATE语句可能并不太难。