【问题标题】:add raw sql where clause to django queryset将原始 sql where 子句添加到 django 查询集
【发布时间】:2016-08-31 18:29:44
【问题描述】:

是否可以向 django 查询集添加额外的原始 sql 子句? 最好将RawSQL 子句用于普通查询集。 它应该是一个普通的查询集而不是一个原始查询集,因为我想在 django 管理员中使用它。

在我的特殊情况下,我想添加一个附加的exists where 子句:

and exists (
   select 1
   from ...
)

在我的具体案例中,我有两个模型 Customer 和 Subscription。 Subscription 有一个 start 和可选的 end 日期字段。

我想拥有一个包含今天当前订阅的所有客户的查询集。像这样的 SQL 查询:

select *
from customers_customer c
where exists (
  select 1
  from subscriptions_subscription sc
  where sc.customer_id = c.id
  and sc.start < current_date
  and (sc.end is null or sc.end > current_date)
)

我无法从中创建查询集。 我到达的最好的东西是这样的:

    cs = Customer.objects.annotate(num_subscriptions=RawSQL(
        '''
        select count(sc.id)
        from subscriptions_customersubscription sc
        where sc.customer_id = customers_customer.id
        and sc.start < current_date
        and (sc.end is null or sc.end > current_date)
        ''', []
    ))

但此查询的性能不如带有where exists 的 SQL 查询。

【问题讨论】:

  • 你能发布你的模型吗?您正在尝试手动连接表,像Customer.objects.filter(subscriptions__start__lt=current_date) 等自然地这样做有问题吗?
  • 好的,自然连接可以正常工作,并且完全符合我的要求......我只是没想到......

标签: django django-queryset


【解决方案1】:

不回答您的问题,但您可以这样查询客户:

from django.db.models import Q

Customer.objects.filter(
    Q(subscription__start__lt=current_date),
    Q(subscription__end=None) | Q (subscription__end__gt=current_date)
).distinct()

【讨论】:

  • 好吧,我没有想到简单的解决方案。虽然这不能回答问题,但它解决了我的问题:upvote
猜你喜欢
  • 2023-01-29
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 1970-01-01
  • 2011-12-03
  • 1970-01-01
  • 2019-11-12
  • 2011-03-17
相关资源
最近更新 更多