我在网上搜索过,只能找到一个看起来像是试图保持查询列表顺序的hackish的博客。我希望使用ORM查询字符串列表,但这样做不会保持列表的顺序。
据我所知,只有拥有要查询的项目的ID时,bulk_query才有效。
有人能推荐一种理想的查询字符串列表并确保对象保持正确顺序吗?
所以在一个完美的世界里,我可以通过做这样的事情来查询一组对象......
Entry.objects.filter(id__in=['list', 'of', 'strings'])
但是,他们没有保持秩序,所以字符串可以在列表之前等...
我看到的唯一的工作,我可能只是累了,或者这可能完全可以接受我不确定是这样做的......
for i in listOfStrings:
object = Object.objects.get(title=str(i))
myIterableCorrectOrderedList.append(object)
谢谢,
答案 0 :(得分:3)
您的解决方案的问题在于它为每个项目执行单独的数据库查询。
如果您使用ids
, This answer会提供正确的解决方案:使用in_bulk
在ID和商品之间创建地图,然后根据需要重新排序。
如果你没有使用ids
,你可以自己创建映射:
values = ['list', 'of', 'strings']
# one database query
entries = Entry.objects.filter(field__in=values)
# one trip through the list to create the mapping
entry_map = {entry.field: entry for entry in entries}
# one more trip through the list to build the ordered entries
ordered_entries = [entry_map[value] for value in values]
(您可以使用index
使用index
保存一行,但由于{{1}}为O(n),因此效果不会对长列表有效。)< / p>
答案 1 :(得分:2)
请记住,最终这一切都是对数据库完成的;这些操作在某处被转换为SQL。
你的Django查询松散地翻译成SQL就像是:
SELECT * FROM entry_table e WHERE e.title IN ("list", "of", "strings");
因此,在某种程度上,您的问题等同于询问如何ORDER BY
在WHERE
子句中指定了某些内容。 (不用说,我希望,这是一个用SQL编写的令人困惑的请求 - 而不是它被设计为使用的方式。)
您可以通过多种方式执行此操作,如StackOverflow [1] [2]上的其他一些答案中所述。但是,正如您所看到的,两者都依赖向数据库添加(临时)信息以对选择进行排序。
实际上,这应该建议正确的答案:您要排序的信息应该在您的数据库中。或者,回到高级Django-land,它应该在你的模型中。当用户添加收藏夹时,请考虑将模型修改为save a timestamp或an ordering,如果这是您要保留的内容。
否则,您将陷入其中一个解决方案,这些解决方案要么从数据库中获取无序数据,然后在Python中“修复”它,要么构建自己的SQL查询并从我链接的解决方案之一实现您自己的丑陋黑客攻击(不要这样做)。
tl; dr “正确”的答案是保持数据库中的排序顺序; “快速修复”是按照您的喜好从数据库中按下未分类的数据。
编辑:显然MySQL has some weird feature可以让你这样做,如果这恰好是你的后端。