在Django Python中,当子查询没有返回结果时,如何将filter和.distinct()替换为另一个filter和.first()?

aiqt4smr  于 2023-06-07  发布在  Go
关注(0)|答案(1)|浏览(189)

我有一个子查询,它根据特定的过滤器返回一些数据。这个特定的过滤器有时会返回null结果,但我想要的是在没有特定过滤器的情况下捕获第一个()结果,如果没有结果返回。

date_filter = Q(start_date__lte=OuterRef('object_start_date'), end_date__gte=OuterRef('object_start_date')) | \
    Q(start_date__lte=OuterRef('object_start_date'), end_date=None)

使用此筛选器的查询

data_subquery = Object.objects.filter(date_filter).filter(user=OuterRef('user')).distinct()

下面将使用此子查询:

main_subquery = Main.annotate(role=Subquery(data_subquery.values('role__name')[:1]))

我已经匿名化的数据,但目标是了解需要...
如果***data_subquery***返回某些内容,则应使用过滤器子查询***datefilter***...否则我不需要这个过滤器,我想用***.first()替换.disctinct()***
Thanks for your help:)
我得到了一个函数来返回特定的数据,这取决于参数中给定的用户和日期...还是第一个但我不知道如何使用函数到子查询;)
我试着补充:

if len(data_subquery) == 0:    
    data_subquery = Object.objects.filter(user=OuterRef('user')).filter()

但它不能与subquery:(

vltsax25

vltsax251#

subqueries是在数据库中计算的,而不是在Python代码中计算的,这就是为什么你会有问题。
你可以通过使用Django的Coalesce数据库函数和Subquery函数来实现你想要的结果。
我们创建两个子查询:第一个带过滤器,第二个不带过滤器。然后,使用Coalesce返回两个subqueries中的第一个非空结果。

from django.db.models import Subquery, OuterRef, Q
from django.db.models.functions import Coalesce

date_filter = Q(start_date__lte=OuterRef('object_start_date'), end_date__gte=OuterRef('object_start_date')) | \
    Q(start_date__lte=OuterRef('object_start_date'), end_date=None)

data_subquery_with_filter = Object.objects.filter(
    date_filter,
    user=OuterRef('user')
).values('role__name')[:1]

data_subquery_without_filter = Object.objects.filter(
    user=OuterRef('user')
).values('role__name')[:1]

main_subquery = Main.objects.annotate(
    role=Coalesce(
        Subquery(data_subquery_with_filter),
        Subquery(data_subquery_without_filter)
    )
)

相关问题