通过id列表选择一组有序的django对象的最佳方法是什么?

时间:2012-01-14 15:38:39

标签: django django-models

我有一个来自Redis的对象ID列表,我想把它们变成一个Django模型对象(或QuerySet)列表。结果应与列表的顺序相同。目前我正在迭代并为每个id执行get。我认为这不是特别有效。

Django有in_bulk,但这不保留顺序。

列表的大小介于10到200个项目之间。

2 个答案:

答案 0 :(得分:3)

Manager.in_bulk只返回一个字典,因此没有办法强迫它有特定的订单。

如果你想要的只是一个匹配ID列表的对象列表,按ID排序,那么这样做:

id_list = [1, 2, 3, 10, 11, 12]
results = MyModel.objects.filter(id__in=id_list).order_by('id')

它可能不如.in_bulk()有效,但它比一次查询一个要好得多。

如果你想要一个非常具体的订单,但是 - 说“按照Redis返回的顺序” - 没有办法让数据库本身这样做。就其本质而言,关系数据库返回一组无序行,除非您应用排序,但该排序必须基于数据库的字段。

那时你最好的选择是使用.in_bulk()获取对象字典,键入ID,然后查找该字典以按照您需要的顺序构建列表:

已编辑:如果您要重新排序结果,则应防止数据库未返回您请求的某些ID。您可以使用results.get(id,None)安全地索引到字典中,并使用filter()从列表中删除空项。

id_list = [10, 11, 12, 1, 2, 3]

# Get all of the items from the database
results = MyModel.objects.in_bulk(id_list)

# re-order the results into the order specified by id_list
ordered_results = [results.get(id,None) for id in id_list]

# remove None items from the ordered results
filtered_results = filter(None, ordered_results)

答案 1 :(得分:0)

您需要的是in field lookp

Model.objects.filter(pk__in = id_list)