Django使用另一个表中的数据更新表

时间:2012-09-20 18:21:36

标签: django django-orm django-database

我有2个表productscatagories通过外键连接。 我需要使用字段products.new_cost更新字段catagories.price_markup,如下所示:

UPDATE products p
INNER JOIN categories c ON p.category_id = c.id
SET p.new_cost = ROUND(p.pleer_cost * (1 + c.price_markup/100), -1)
WHERE p.update = 1

在SQL中它很容易,但是如何使用Django ORM来做呢?

我的简化尝试不起作用Cannot resolve keyword 'category.price_markup' into field.

Product.actived.select_related('category').filter(update=1)).update(new_cost=F('pleer_cost') * F('category.price_markup'))

5 个答案:

答案 0 :(得分:15)

注意:我的答案现已过时,Django 1.11 introduced OuterRef实现了此功能。检查下面的Andrey Berenda答案。

根据documentation,不支持使用join子句的更新,请参阅:

  

但是,与filter和exclude子句中的F()对象不同,您不能   在更新中使用F()对象时引入连接 - 您只能   正在更新的模型的本地参考字段。如果你试图   引入一个带F()对象的连接,将引发FieldError:

# THIS WILL RAISE A FieldError
>>> Entry.objects.update(headline=F('blog__name'))

另外,根据这个issue,这是设计上的,并且没有计划在不久的将来改变它:

  

这里的实际问题似乎是加入的F()子句不是   在update()语句中允许。这是设计的;支持连接   在update()子句中由于固有而被显式删除   在一般情况下支持他们的并发症。

答案 1 :(得分:13)

您不能使用F,但可以使用Subquery和OuterRef:

from django.db.models import Subquery, OuterRef

cost = Category.objects.filter(
    id=OuterRef('product_id')
).values_list(
    'price_markup'
)[:1]

Product.objects.update(
    new_cost=Subquery(cost)
)

答案 2 :(得分:0)

rows = Product.objects.filter(old_field__isnull=False)
for row in rows:
     row.new_field = row.old_field.subfield
Product.objects.bulk_update(rows, ['new_field'])

答案 3 :(得分:-2)

AFAIU可以与

协同工作
for row in ModelName.objects.filter(old_field__isnull=False):
     row.new_field = row.old_field.subfield
     row.save()

答案 4 :(得分:-9)

更新:它似乎无法正常运行或已过期。鉴于我在大约6年内没有使用过Django,我建议你看看这个问题的其他答案,而不是这个问题。如果可能的话,我希望这个没有标记并删除,因为我很确定此时它具有误导性并且不再有效(给出-10分)。

Django对相关字段使用__(双下划线)。将category.price_markup更改为category__price_markup,您应该明确。