以自定义顺序获取多个对象的优雅方式

时间:2017-11-20 09:58:25

标签: django django-queryset

从django中的数据库中以某种自定义顺序获取多个对象的优雅方法是什么?

例如,假设您有一些产品,每个产品都有其名称,并且您希望获取其中三个产品以在某个固定的自定义顺序中在您的网站页面上连续显示。假设您要显示的产品名称依次为:["Milk", "Chocolate", "Juice"]

一个人可以做到

unordered_products = Product.objects.filter(name__in=["Milk", "Chocolate", "Juice"])
products = [
   unordered_products.filter(name="Milk")[0],
   unordered_products.filter(name="Chocolate")[0],
   unordered_products.filter(name="Juice")[0],
]

可以改进后期获取订购部分,以改为使用name - 索引字典:

ordered_product_names = ["Milk", "Chocolate", "Juice"]
products_by_name = dict((x.name, x) for x in unordered_products)
products = [products_by_name[name] for name in ordered_product_names]

但是有更优雅的方式吗?例如,以某种方式将所需的订单传达给DB层,或者返回按名称分组的产品(聚合似乎与我想要的类似,但我想要实际的对象,而不是关于它们的统计数据。)

2 个答案:

答案 0 :(得分:3)

如果您正在获取的对象之间没有任何关系,并且您仍希望以特定(自定义)顺序获取(或排列)它们,则可以尝试这样做:

unordered_products = Product.objects.filter(name__in=["Milk", "Chocolate", "Juice"])

product_order = ["Milk", "Chocolate", "Juice"]

preserved = Case(*[When(name=name, then=pos) for pos, name in enumerate(product_order)])

ordered_products = unordered_products.order_by(preserved)

希望它有所帮助!

答案 1 :(得分:0)

从模型中尝试使用元类:

class Meta:
    ordering = ('name', 'related__name', )

这会根据您指定的字段

订购您的记录

然后:巧克力,巧克力蓝,巧克力白,果汁绿,果汁XXX,牛奶,乳白色,牛奶YYYY应该在你拿到时保持这个顺序