在计数之前排除相关对象
Exclude related objects before Count
例如我有 3 个模型 User
、A
、B
。
class A(models.Model):
creator = models.ForeignKey(
'users.User', on_delete=models.CASCADE, related_name='A_set'
)
class B(models.Model):
user = models.ForeignKey(
'users.User', on_delete=models.CASCADE, related_name='B_set'
)
a_model = models.ForeignKey(
'a.A', on_delete=models.CASCADE, related_name='B_set'
)
我想获得 B
的计数,其中 user
不是 a_model 对象的 creator
。
我试过查询:
`User.objects.prefetch_related('B_set').last().B_set.exclude(a_model__creator=F('user')).count()`
这是我对注释的尝试:
User.objects.annotate(b_count=Count('B_set', filter=(~Q(B_set__A__creator=F('user')))))
但是我收到一个错误:
Cannot resolve keyword 'user' into field.
然后它建议我与用户相关的字段。我也尝试用 F()
将 user
更改为 B_set__user
但它没有帮助。
加上你的注释:
User.objects.annotate(
b_count=Count('B_set', filter=(~Q(B_set__A__creator=<s>F('user')</s>)))
)
您的 F(..)
属性指的是 假设的 User.user
字段,但是 User
有(可能)没有 user
场.
如果你想在这里引用"self",你可以使用F('pk')
(或F('id')
,如果id
是主键),所以你可以将此表达式写为:
User.objects.annotate(
b_count=Count('B_set', filter=~Q(B_set__a__model__creator=<b>F('pk')</b>))
)
这会导致如下查询:
SELECT user.*,
COUNT(
CASE WHEN NOT a.creator_id = user.id AND a.creator_id IS NOT NULL
THEN b.id ELSE NULL END
) AS b_count
FROM user
LEFT OUTER JOIN b ON user.id = b.user_id
LEFT OUTER JOIN a ON b.a_model_id=a.id
GROUP BY user.id
例如我有 3 个模型 User
、A
、B
。
class A(models.Model):
creator = models.ForeignKey(
'users.User', on_delete=models.CASCADE, related_name='A_set'
)
class B(models.Model):
user = models.ForeignKey(
'users.User', on_delete=models.CASCADE, related_name='B_set'
)
a_model = models.ForeignKey(
'a.A', on_delete=models.CASCADE, related_name='B_set'
)
我想获得 B
的计数,其中 user
不是 a_model 对象的 creator
。
我试过查询:
`User.objects.prefetch_related('B_set').last().B_set.exclude(a_model__creator=F('user')).count()`
这是我对注释的尝试:
User.objects.annotate(b_count=Count('B_set', filter=(~Q(B_set__A__creator=F('user')))))
但是我收到一个错误:
Cannot resolve keyword 'user' into field.
然后它建议我与用户相关的字段。我也尝试用 F()
将 user
更改为 B_set__user
但它没有帮助。
加上你的注释:
User.objects.annotate(
b_count=Count('B_set', filter=(~Q(B_set__A__creator=<s>F('user')</s>)))
)
您的 F(..)
属性指的是 假设的 User.user
字段,但是 User
有(可能)没有 user
场.
如果你想在这里引用"self",你可以使用F('pk')
(或F('id')
,如果id
是主键),所以你可以将此表达式写为:
User.objects.annotate(
b_count=Count('B_set', filter=~Q(B_set__a__model__creator=<b>F('pk')</b>))
)
这会导致如下查询:
SELECT user.*,
COUNT(
CASE WHEN NOT a.creator_id = user.id AND a.creator_id IS NOT NULL
THEN b.id ELSE NULL END
) AS b_count
FROM user
LEFT OUTER JOIN b ON user.id = b.user_id
LEFT OUTER JOIN a ON b.a_model_id=a.id
GROUP BY user.id