基于外键值/连接字段的 Django 条件更新
Django Conditional update based on Foreign key values / joined fields
我正在尝试根据外键字段的值进行条件更新。示例:
Model Kid: id, parent (a foreign key to Parent), has_rich_parent
Model Parent: id, income
假设我有一组 A 的查询。我想根据一个 update
中 Kid 的父项的 age
的值更新 A 中每个项目的 has_guardian
。我想做的是
queryset_of_kids.update(
has_rich_parent=Case(
When(parent__income__gte=10, then=True)
default=False
)
)
但这给我一个错误 Joined field references are not permitted in this query
。我将其理解为 update
s.
中不允许加入字段/追求外键关系
我想知道是否有任何其他方法可以完成同样的事情,例如在一次更新调用中更新此查询集?我的情况有几个我想验证的字段,而不仅仅是 income
在这里,所以如果我尝试先过滤然后更新,调用次数将与我想要的参数数量成线性关系filter/update.
提前致谢!
以下是我假设您使用的模型:
from django.db import models
class Kid(models.Model):
parent = models.ForeignKey('Parent', on_delete=models.CASCADE)
has_rich_parent = models.BooleanField(default=False)
class Parent(models.Model):
income = models.IntegerField()
您可以使用 Subquery
来更新 has_rich_parent
字段。
- 子查询使用
.filter(pk=OuterRef('pk'))
. 对周围查询的主键 pk
进行过滤
- 它使用
Q
查询object来获取parent收入是否>=10。
from .models import Kid, Parent
from django.db.models import Q, Subquery, OuterRef
Kid.objects.update(has_rich_parent=Subquery(
Kid.objects.filter(pk=OuterRef('pk'))
.values_list(Q(parent__income__gte=10))))
该命令产生以下 SQL 查询:
UPDATE "more_kids_kid"
SET "has_rich_parent" = (
SELECT (U1."income" >= 10) AS "q1"
FROM "more_kids_kid" U0
INNER JOIN "more_kids_parent" U1 ON (U0."parent_id" = U1."id")
WHERE U0."id" = ("more_kids_kid"."id")
)
此查询不如 SELECT
-then-UPDATE
查询有效。但是,您的数据库可能会对其进行优化。
我正在尝试根据外键字段的值进行条件更新。示例:
Model Kid: id, parent (a foreign key to Parent), has_rich_parent
Model Parent: id, income
假设我有一组 A 的查询。我想根据一个 update
中 Kid 的父项的 age
的值更新 A 中每个项目的 has_guardian
。我想做的是
queryset_of_kids.update(
has_rich_parent=Case(
When(parent__income__gte=10, then=True)
default=False
)
)
但这给我一个错误 Joined field references are not permitted in this query
。我将其理解为 update
s.
我想知道是否有任何其他方法可以完成同样的事情,例如在一次更新调用中更新此查询集?我的情况有几个我想验证的字段,而不仅仅是 income
在这里,所以如果我尝试先过滤然后更新,调用次数将与我想要的参数数量成线性关系filter/update.
提前致谢!
以下是我假设您使用的模型:
from django.db import models
class Kid(models.Model):
parent = models.ForeignKey('Parent', on_delete=models.CASCADE)
has_rich_parent = models.BooleanField(default=False)
class Parent(models.Model):
income = models.IntegerField()
您可以使用 Subquery
来更新 has_rich_parent
字段。
- 子查询使用
.filter(pk=OuterRef('pk'))
. 对周围查询的主键 - 它使用
Q
查询object来获取parent收入是否>=10。
pk
进行过滤
from .models import Kid, Parent
from django.db.models import Q, Subquery, OuterRef
Kid.objects.update(has_rich_parent=Subquery(
Kid.objects.filter(pk=OuterRef('pk'))
.values_list(Q(parent__income__gte=10))))
该命令产生以下 SQL 查询:
UPDATE "more_kids_kid"
SET "has_rich_parent" = (
SELECT (U1."income" >= 10) AS "q1"
FROM "more_kids_kid" U0
INNER JOIN "more_kids_parent" U1 ON (U0."parent_id" = U1."id")
WHERE U0."id" = ("more_kids_kid"."id")
)
此查询不如 SELECT
-then-UPDATE
查询有效。但是,您的数据库可能会对其进行优化。