【问题标题】:What is the best way to use query with a list and keep the list order? [duplicate]将查询与列表一起使用并保持列表顺序的最佳方法是什么? [复制]
【发布时间】:2014-04-09 22:50:58
【问题描述】:

我在网上搜索过,只能找到一个博客,它似乎是为了保持查询列表的顺序而进行的骇人听闻的尝试。我希望使用带有字符串列表的 ORM 进行查询,但是这样做并不能保持列表的顺序。

据我了解,bulk_query 仅在您拥有要查询的项目的 ID 时才有效。

谁能推荐一种通过字符串列表进行查询并确保对象保持正确顺序的理想方法?

所以在一个完美的世界里,我可以通过做这样的事情来查询一组对象......

Entry.objects.filter(id__in=['list', 'of', 'strings'])

但是,它们不保持顺序,因此字符串可能在列表等之前...

我看到的唯一解决方法,我可能只是累了,或者这可能完全可以接受,我不确定这样做......

for i in listOfStrings:
    object = Object.objects.get(title=str(i))
    myIterableCorrectOrderedList.append(object)

谢谢,

【问题讨论】:

  • 您能否举一个查询示例以及您期望得到什么?我可以在脑海中想象一些东西,但我不知道我所想象的是否是你真正想要的。
  • 我已经更新了我的问题,基本上我的解决方案是可行的,看起来肯定有更好的东西吗?
  • 我看到了那个答案,但它似乎并不适用。基本上我有一个电影列表,这是某人最喜欢的列表,要查询该列表,我需要按照他们给它们的顺序排列。 (按最喜欢的)它们不能按字母顺序、ID 等排序...我本可以为他们最喜欢的电影排名建立一个多对多表,但这有点事后才想到。

标签: django


【解决方案1】:

您的解决方案的问题在于它对每个项目执行单独的数据库查询。

如果您使用 idsThis 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 为自己节省一行,就像在this example 中一样,但由于index 是O(n),因此对于长列表来说性能并不好。)

【讨论】:

  • 哇,这是一个完美的例子,而且效果很好。我自己不会得到那个。谢谢,Python 和 Django 万岁! (来自 .NET 开发人员)我看到了 Roseman 的示例,但认为它不适用于这个特定问题,而且它的布局肯定不如您的示例那么完美。再次感谢,我认为这对其他人会有很大帮助。
【解决方案2】:

请记住,最终这一切都是在数据库中完成的;这些操作在某处被转换为 SQL。

您的 Django 查询松散地翻译成 SQL 会是这样的:

SELECT * FROM entry_table e WHERE e.title IN ("list", "of", "strings");

因此,在某种程度上,您的问题等同于询问如何ORDER BYWHERE 子句中指定的顺序。 (不用说,我希望这是一个用 SQL 编写的令人困惑的请求——而不是它的设计使用方式。)

您可以通过多种方式执行此操作,如 StackOverflow [1][2] 上的其他一些答案中所述。但是,如您所见,两者都依赖于向数据库添加(临时)信息来对选择进行排序。

真的,这应该是正确的答案:您要排序的信息应该在您的数据库中。或者,回到高级 Django 领域,它应该在您的模型中。考虑在用户添加收藏夹时将模型修改为 save a timestampan ordering,如果这是您想要保留的内容。

否则,您会遇到以下解决方案之一:从数据库中获取无序数据然后在 Python 中“修复”它,或者构建您自己的 SQL 查询并从我链接的解决方案之一实现您自己的丑陋黑客(不要这样做)。

tl;dr“正确”的答案是保持数据库中的排序顺序; “快速修复”是在 Python 中根据自己的喜好从数据库中按摩未排序的数据。

编辑:显然MySQL has some weird feature 可以让你这样做,如果这恰好是你的后端的话。

【讨论】:

    猜你喜欢
    • 2010-09-16
    • 1970-01-01
    • 2017-08-23
    • 2012-04-22
    • 1970-01-01
    • 2012-11-30
    • 2020-10-09
    • 2015-05-10
    • 1970-01-01
    相关资源
    最近更新 更多