Django中如何按created_at字段对多模型合并列表降序排序?
解决多模型QuerySet合并后按created_at排序的问题
错误原因分析
你之前的两种写法都存在问题:
all_user_objects.order_by('-created_at'):all_user_objects是Python列表,而order_by()是Django QuerySet的专属方法,列表没有这个属性,调用会直接报错。list(chain(...), key=attrgetter('-created_at')):list()函数仅接受一个可迭代对象参数,key是sorted()函数的参数,不能直接传给list(),属于语法错误。
正确实现方法
方法一:合并后用sorted() + attrgetter排序
先将多个QuerySet合并为列表,再通过sorted()排序,用attrgetter获取对象的created_at属性,reverse=True实现从新到旧的降序排列:
from itertools import chain from operator import attrgetter query_1 = Room.objects.all() query_2 = Apartment.objects.all() query_3 = Plot.objects.all() # 合并QuerySet为列表后排序 all_user_objects = list(chain(query_1, query_2, query_3)) all_user_objects_sorted = sorted(all_user_objects, key=attrgetter('created_at'), reverse=True)
方法二:直接对chain结果排序(更高效)
无需先转换为列表,直接对chain返回的可迭代对象排序后再转列表,减少一次内存占用:
from itertools import chain from operator import attrgetter query_1 = Room.objects.all() query_2 = Apartment.objects.all() query_3 = Plot.objects.all() all_user_objects_sorted = sorted(chain(query_1, query_2, query_3), key=attrgetter('created_at'), reverse=True)
方法三:用lambda表达式替代attrgetter
如果不想导入attrgetter,可以用lambda表达式实现相同逻辑:
from itertools import chain query_1 = Room.objects.all() query_2 = Apartment.objects.all() query_3 = Plot.objects.all() all_user_objects = list(chain(query_1, query_2, query_3)) all_user_objects_sorted = sorted(all_user_objects, key=lambda obj: obj.created_at, reverse=True)
内容的提问来源于stack exchange,提问作者Maddie Graham
相关产品推荐
相关产品推荐

