简体   繁体   English

从 id 列表中手动在 Django 中创建 QuerySet

[英]Creating a QuerySet manually in Django from list of ids

Let's say I have a model My_model and I have a list of ids for this model;假设我有一个 model My_model并且我有这个 model 的 ID 列表;

my_ids = [3,2,1,42]

Now I want to get a QuerySet with the My_model.objects of the ids.现在我想获得一个带有 ID 的My_model.objects的 QuerySet。 I already found this solution , but it doesn't work for me, because I want to have the objects in the QuerySet in the same order as the ids in my_ids .我已经找到了这个解决方案,但它对我不起作用,因为我希望 QuerySet 中的对象与my_ids中的 id 的顺序相同。

How can I turn a list of ids in a QuerySet in Django and Python?如何在 Django 和 Python 的 QuerySet 中打开 id 列表?

It indeed does not care about the order, since the query looks like:它确实不关心顺序,因为查询看起来像:

SELECT model.*
FROM model
WHERE model.pk IN (3, 2, 1, 42)

The database can return the values in any order it wants.数据库可以按照它想要的任何顺序返回值。 Depending on the database you use, the indexing mechanism, etc. the order can be "deterministic", but it is even possible that it will return records completely random.根据您使用的数据库、索引机制等,顺序可以是“确定的”,但它甚至有可能返回完全随机的记录。

You can order these, with a rather complicates expression:您可以使用相当复杂的表达式来订购这些:

from django.db.models import Case, IntegerField, Value, When

my_ids = [3,2,1,42]

Model.objects.filter(
    pk__in=my_ids
).order_by(
    Case(
        *[When(pk=pk, then=Value(i)) for i, pk in enumerate(my_ids)],
        output_field=IntegerField()
    ).asc()
)

This is still a QuerySet , and can be used for lazy querying purposes, but the question remains why you want to sort the elements based on the order of the primary keys.这仍然是一个QuerySet ,可以用于惰性查询目的,但问题仍然是为什么要根据主键的顺序对元素进行排序。 Usually the model (or a related model) contains more "interesting" ways to order elements.通常 model(或相关型号)包含更多“有趣”的元素排序方式。

You can use in_bulk() :您可以使用in_bulk()

queryset = Foo.objects.in_bulk(my_ids)

However, this will have the same problem.但是,这将有同样的问题。 This isn't a limitation of Django, but of SQL.这不是 Django 的限制,而是 SQL 的限制。 The database will give you back the data however it wants unless you explicitly order it, and there's not really a good way to arbitrarily order things.除非您明确订购,否则数据库会根据需要将数据返回给您,并且没有真正的好方法来任意订购。

So the answer is, you can't, easily.所以答案是,你不能,很容易。 You could possibly do weird things with CASE in SQL, but this will possibly be slow.你可能会用 SQL 中的CASE做一些奇怪的事情,但这可能会很慢。

Probably the simplest way is to convert the queryset to a list and then do your custom ordering in Python, something like:可能最简单的方法是将查询集转换为列表,然后在 Python 中进行自定义排序,例如:

objs = sorted(list(queryset), key=lambda x: my_ids.index(x.id))

Edit: Willem's answer does weird things with case that is probably faster than this, but I still wouldn't want to grab stuff in arbitrary orders if you care about speed.编辑:Willem 的回答用可能比这更快的case做了奇怪的事情,但如果你关心速度,我仍然不想按任意顺序抓取东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM