Django:更新多个对象属性

时间:2016-12-20 23:50:55

标签: python django django-orm

有没有一种更有效的方法可以用F表达式做到这一点?一些如何减少击中DB?

# 1st way hits DB twice per object
def something():
  pks = [4, 2, 1, 3, 0]
  for i in range(len(pks)):
    mymodel.objects.get(pk=pks[i]).update(attr=i)

# 2nd way hits DB once per obj and once for the queryset
def something():
  pks = [4, 2, 1, 3, 0]
  order = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pks)])
  query = mymodel.objects.filter(pk__in=pks).order_by(order)
  for i in range(len(query)):
    query[i].attr = i
    query[i].save()

编辑以使变量保持一致。

2 个答案:

答案 0 :(得分:4)

通常要避免使用多个数据库查询而不是一个大型查询。但是你的情况似乎是一个例外。 (注意:我根据提供的信息做出这个答案。请不要编辑你的问题,说我的意思是......)

以下查询将非常快,无论您有多少条记录,因为它从主键检索单个项目。所有RDBMS都旨在很好地处理这个问题。

mymodel.objects.get(pk=a[i]) 

Hower你可以使你的功能更有效:

def something():
  pks = [4, 2, 1, 3, 0]
  for i in range(len(a)):
    mymodel.objects.filter(pk=a[i]).update(attr=i)

现在每个对象只能击中一次DB。以上查询只是转换为

 UPDATE mapp_mymodel SET attr=i where pk=1

答案 1 :(得分:0)

如果我没弄错的话,你可以做一些像

这样的事情
pks = [4, 2, 1, 3, 0]
mymodel.object.filter(pk__in=pks).update(attr='test')

除非您尝试使用for循环索引作为属性值,否则这不起作用。