Django 1.10.6
Asset.objects.annotate(
coupon_saved=Count(
Q(coupons__device_id='8ae83c6fa52765061360f5459025cb85e6dc8905')
)
).all().query
会产生以下查询:
SELECT
"assets_asset"."id",
"assets_asset"."title",
"assets_asset"."description",
"assets_asset"."created",
"assets_asset"."modified",
"assets_asset"."uid",
"assets_asset"."org_id",
"assets_asset"."subtitle",
"assets_asset"."is_active",
"assets_asset"."is_generic",
"assets_asset"."file_standalone",
"assets_asset"."file_ios",
"assets_asset"."file_android",
"assets_asset"."file_preview",
"assets_asset"."json_metadata",
"assets_asset"."file_icon",
"assets_asset"."file_image",
"assets_asset"."video_mobile",
"assets_asset"."video_standalone",
"assets_asset"."file_coupon",
"assets_asset"."where_to_buy",
COUNT("games_coupon"."device_id" = 8ae83c6fa52765061360f5459025cb85e6dc8905) AS "coupon_saved"
FROM
"assets_asset"
LEFT OUTER JOIN
"games_coupon"
ON ("assets_asset"."id" = "games_coupon"."asset_id")
GROUP BY
"assets_asset"."id"
我需要将device_id=X
纳入 LEFT OUTER JOIN 定义。
答案 0 :(得分:0)
<强> TL; DR:强>
条件应该在filter
。
qs = (
Asset.objects
.filter(coupons__device_id='8ae83c6fa52765061360f5459025cb85e6dc8905')
.annotate(coupon_saved=Count('coupons'))
)
如果您只想count > 0
,则可以对其进行过滤。
qs = qs.filter(coupon_saved__gt=0)
脚注:将一对多查询编译为LEFT OUTER JOIN
,以便能够获得零子项的基础对象(资产)。 Django中的JOIN每次都在ForeignKey上基于主键,或类似地在OneToOne或ManyToMany上,其他条件被编译为WHERE。
注释中的条件(您使用过的)是可能的,例如作为Conditional Expressions的一部分,但正确使用和使用它会更复杂,例如如果您希望通过一个没有子查询的查询获得许多条件的聚合,并且可以接受完整扫描。这可能不是问题的主题。