【问题标题】:I am getting order_by fields in the form of a alphabetical order. I want to order_by by multiple values of field with django orm. List is like below:我以字母顺序的形式获取 order_by 字段。我想通过 django orm 的多个字段值来 order_by。清单如下:
【发布时间】:2021-04-21 11:29:31
【问题描述】:
orderbyList = ['Day','Afternoon','Night']
我写的查询是这样的:
modelclassinstance.objects.all().order_by(shift_name=*orderbyList)
-
shift_name 是列的名称,'Day','Afternoon','Night' 是
里面的价值观
-
我的最终输出应该是这样的
首先记录全天,然后是下午,然后是晚上,不按字母顺序。
【问题讨论】:
标签:
python-3.x
django
django-models
django-rest-framework
django-views
【解决方案1】:
您可以使用 Conditional Expressions [Django docs] 为 orderbyList 中的每个值注释一个值,查询集将根据该值进行排序:
from django.db.models import Case, Value, When
orderbyList = ['Day','Afternoon','Night']
order_case = Case(
*[When(shift_name=value, then=Value(index)) for index, value in enumerate(orderbyList)],
default=Value(len(orderbyList))
)
queryset = modelclassinstance.objects.annotate(order_case=order_case).order_by('order_case')
注意:虽然此解决方案可行,但您应该考虑让 shift_name 处于 单独 模型中
一些字段来指示它在该字段上的排序和顺序。您的
当前模型应该只具有该模型的外键
shift_name。这样在效率方面会更好。
【解决方案2】:
您需要使用条件表达式(Case/When 语法):https://docs.djangoproject.com/en/3.2/ref/models/conditional-expressions/
比如:
from django.db.models import Value, Case, When, IntegerField
modelclassinstance.objects.annotate(
custom_order=Case(
When(shift_name='Day', then=Value(1)),
When(shift_name='Afternoon', then=Value(2)),
When(shift_name='Night', then=Value(3)),
output_field=IntegerField()
)
).order_by('custom_order')