如何按指定护照号列表顺序获取Django Users QuerySet?
按指定护照号顺序获取Django Users QuerySet的问题
我需要根据给定的护照号列表,按列表中的顺序返回对应的Users QuerySet。护照号列表如下:
lst = ['AA1111111', 'AD2222222', 'AA3333333', 'AA4444444', 'АВ5555555']
我尝试了两种方法,但都无法得到预期的顺序:
方法一:循环合并QuerySet
empty_queryset = Users.objects.none() for passport_number in lst: user = Users.objects.filter(passport_number__exact=passport_number) empty_queryset |= user
预期顺序:
<QuerySet [<Users: AA1111111>, <Users: AD2222222>, <Users: AA3333333>, <Users: AA4444444>, <Users: АВ5555555>]>
实际返回顺序(混乱):
<QuerySet [<Users: АВ5555555>, <Users: AA1111111>, <Users: AD2222222>, <Users: AA3333333>, <Users: AA4444444>]>
方法二:使用__in查询
Users.objects.filter(passport_number__in=[i for i in lst])
此方法同样无法返回与输入列表一致的顺序。
解决方案:自定义排序规则
要按输入列表的顺序返回QuerySet,需利用Django的Case和When构建自定义排序逻辑,代码如下:
from django.db.models import Case, When lst = ['AA1111111', 'AD2222222', 'AA3333333', 'AA4444444', 'АВ5555555'] # 为每个护照号分配对应的排序索引 ordering = Case( *[When(passport_number=pn, then=idx) for idx, pn in enumerate(lst)] ) # 查询并按自定义规则排序 users = Users.objects.filter(passport_number__in=lst).order_by(ordering)
原理说明
- 上述代码通过
enumerate为列表中的每个护照号赋予一个顺序索引,再用Case和When将索引作为排序依据。 - 数据库会按照这个指定的索引值排序,最终返回的QuerySet顺序将与输入列表完全一致。
原方法失效原因
- 方法一中,合并多个QuerySet时,最终结果会遵循数据库的默认排序规则(通常是主键ID),无法保留循环时的顺序。
- 方法二中,
__in查询的结果顺序由数据库自身的索引或默认排序决定,与传入列表的顺序无关。
内容的提问来源于stack exchange,提问作者HollowPillow
相关产品推荐
相关产品推荐

