Django 多个 exists() 聚合
Django multiple exists() aggregate
class Order(models.Model):
# Some fields..
status = models.IntegerField()
user = models.ForeignKey(User)
状态字段可以取四个值:1,2,3,4
我想执行一个查询,它将 return 一个 单行 行(元组),带有一个指示符,根据:
if in the queryset there is a row with status=1, return 1
elif there's row with status=3, return 3
elif there's row with status=4, return 4
elif there's row with status=2, return 2
按此优先级(即按此顺序,类似于 switch-case 的工作方式)。
我向他们查询特定用户以显示一些状态消息。所以它应该像这样开始:
Order.objects.filter(user=request.user) # ...? .aggregate() maybe ?
我只需要指标,不需要任何订单对象。
我认为在数据库级别它会变成 Case
之类的东西,但我无法让它与 django 一起工作。
编辑:为了更好地解释,我可以那样做
if Order.objects.filter(user=request.user, status=1).exists():
return 1
elif Order.objects.filter(user=request.user, status=3).exists():
return 3
elif Order.objects.filter(user=request.user, status=4).exists():
return 4
elif Order.objects.filter(user=request.user, status=2).exists():
return 2
但显然我想避免进行 4 次查询..
Order.objects.annotate(order_status=models.Case(
models.When(status=1, then=0),
models.When(status=3, then=1),
models.When(status=4, then=2),
models.When(status=2, then=3),
default=models.F('status'),
output_field=models.IntegerField(),
),).aggregate(models.Min('order_status'))
并且需要一些字典来映射状态
order_statuses = Order.objects.filter(user=request.user).values_list('status', flat=True)
这将 return 您的状态列表。现在您可以检查为:
if 1 in order_statuses:
return 1
elif 2 in order_statuses:
return 3
elif 3 in order_statuses:
return 4
elif 4 in order_statuses:
return 2
这样您就可以在 Django 服务器上进行计算,而不是增加数据库的额外负载。
你可以这样做:
# This will return a value of None, if no matching Order object exists,
# or the lowest status that exists:
return Order.objects.filter(
user=request.user
).order_by(
'status'
).values_list(
'status', flat=True
).first()
class Order(models.Model):
# Some fields..
status = models.IntegerField()
user = models.ForeignKey(User)
状态字段可以取四个值:1,2,3,4
我想执行一个查询,它将 return 一个 单行 行(元组),带有一个指示符,根据:
if in the queryset there is a row with status=1, return 1
elif there's row with status=3, return 3
elif there's row with status=4, return 4
elif there's row with status=2, return 2
按此优先级(即按此顺序,类似于 switch-case 的工作方式)。 我向他们查询特定用户以显示一些状态消息。所以它应该像这样开始:
Order.objects.filter(user=request.user) # ...? .aggregate() maybe ?
我只需要指标,不需要任何订单对象。
我认为在数据库级别它会变成 Case
之类的东西,但我无法让它与 django 一起工作。
编辑:为了更好地解释,我可以那样做
if Order.objects.filter(user=request.user, status=1).exists():
return 1
elif Order.objects.filter(user=request.user, status=3).exists():
return 3
elif Order.objects.filter(user=request.user, status=4).exists():
return 4
elif Order.objects.filter(user=request.user, status=2).exists():
return 2
但显然我想避免进行 4 次查询..
Order.objects.annotate(order_status=models.Case(
models.When(status=1, then=0),
models.When(status=3, then=1),
models.When(status=4, then=2),
models.When(status=2, then=3),
default=models.F('status'),
output_field=models.IntegerField(),
),).aggregate(models.Min('order_status'))
并且需要一些字典来映射状态
order_statuses = Order.objects.filter(user=request.user).values_list('status', flat=True)
这将 return 您的状态列表。现在您可以检查为:
if 1 in order_statuses:
return 1
elif 2 in order_statuses:
return 3
elif 3 in order_statuses:
return 4
elif 4 in order_statuses:
return 2
这样您就可以在 Django 服务器上进行计算,而不是增加数据库的额外负载。
你可以这样做:
# This will return a value of None, if no matching Order object exists,
# or the lowest status that exists:
return Order.objects.filter(
user=request.user
).order_by(
'status'
).values_list(
'status', flat=True
).first()