【问题标题】:Django ORM and left join - through annotate?Django ORM 和左连接 - 通过注释?
【发布时间】:2017-11-27 15:54:12
【问题描述】:
Asset.objects.filter(
            campaigns__games__pk=_version.game_id,
            campaigns__is_active=True,
            campaigns__games__active=True,
            is_active=True).select_related('org').all()

此查询返回 49 条记录

Asset.objects.filter(
            campaigns__games__pk=_version.game_id,
            campaigns__is_active=True,
            campaigns__games__active=True,
            is_active=True,
            coupons__session__device_id='GUID').select_related('org').all()

只有 ONE,因为它使 INNER JOIN 到 Asset.coupons.session 表。 实际上,我想检索与第一个查询中相同的 49 条记录,但如果存在会话表,则需要从会话表中获取更多信息。

所以我想要实现的是 LEFT JOIN,所以如果给定资产会话存在 - 然后我在我的 API 响应中设置一个标志“is_saved=True”。

据我了解 - 正确的方法是使用 AnnotateCase/When

如何实现?

【问题讨论】:

  • 你能发布你的模型吗?

标签: django django-models django-orm


【解决方案1】:

好吧,您要求 ORM 返回具有 Sessiondevice_id 字段设置为 GUIDAssets,所以这绝对是 INNER JOIN - Session 必须存在对于给定的Asset,以便您能够查询其上的字段。

你应该能够实现你所需要的使用:

Asset.objects.filter(
    campaigns__games__pk=_version.game_id,
    campaigns__is_active=True,
    campaigns__games__active=True,
    is_active=True,
).annotate(
    session__device_id=F('coupons__session__device_id')
    # any other fields can go here
).select_related(
    'org'
).all()

或者,如果您只在布尔值 True 之后,如果 coupons__session 不为 NULL,则使用 Exists 应该没问题。

【讨论】:

    猜你喜欢
    • 2020-05-18
    • 2020-12-10
    • 1970-01-01
    • 2011-09-23
    • 2018-06-18
    • 2021-05-25
    • 2021-12-03
    • 2018-10-10
    相关资源
    最近更新 更多