从 id 列表在 Django 中手动创建一个 QuerySet
Creating a QuerySet manually in Django from list of ids
假设我有一个模型 My_model
并且我有这个模型的 ID 列表;
my_ids = [3,2,1,42]
现在我想获得一个带有 My_model.objects
个 ID 的 QuerySet。
我已经找到 this solution,但它对我不起作用,因为我希望 QuerySet 中的对象与 my_ids
.
中的 id 的顺序相同
如何在 Django 和 Python 中转换 QuerySet 中的 ID 列表?
您可以使用 in_bulk()
:
queryset = Foo.objects.in_bulk(my_ids)
但是这样也会有同样的问题。这不是 Django 的限制,而是 SQL 的限制。除非您明确订购,否则数据库会根据需要返回给您数据,并且没有真正的任意订购事物的好方法。
所以答案是,你不能,很容易。您可能会在 SQL 中使用 CASE
做一些奇怪的事情,但这可能会很慢。
可能最简单的方法是将查询集转换为列表,然后在 Python 中进行自定义排序,例如:
objs = sorted(list(queryset), key=lambda x: my_ids.index(x.id))
编辑:Willem 的回答用 case
做了奇怪的事情,可能比这更快,但如果你关心速度,我仍然不想以任意顺序获取东西。
它确实不关心顺序,因为查询看起来像:
SELECT model.*
FROM model
WHERE model.pk <b>IN (3, 2, 1, 42)</b>
数据库可以return 以任何顺序排列值。根据您使用的数据库、索引机制等,顺序可以是 "deterministic",但甚至有可能 return 记录完全随机。
你可以订购这些,用一个相当复杂的表达:
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(
*[<b>When(pk=pk, then=Value(i)) for i, pk in enumerate(my_ids)</b>],
output_field=IntegerField()
)<b>.asc()</b>
)
这仍然是一个QuerySet
,可以用于惰性查询目的,但问题仍然是为什么要根据的顺序对元素进行排序主键。通常模型(或相关模型)包含更多 "interesting" 元素排序方式。
假设我有一个模型 My_model
并且我有这个模型的 ID 列表;
my_ids = [3,2,1,42]
现在我想获得一个带有 My_model.objects
个 ID 的 QuerySet。
我已经找到 this solution,但它对我不起作用,因为我希望 QuerySet 中的对象与 my_ids
.
如何在 Django 和 Python 中转换 QuerySet 中的 ID 列表?
您可以使用 in_bulk()
:
queryset = Foo.objects.in_bulk(my_ids)
但是这样也会有同样的问题。这不是 Django 的限制,而是 SQL 的限制。除非您明确订购,否则数据库会根据需要返回给您数据,并且没有真正的任意订购事物的好方法。
所以答案是,你不能,很容易。您可能会在 SQL 中使用 CASE
做一些奇怪的事情,但这可能会很慢。
可能最简单的方法是将查询集转换为列表,然后在 Python 中进行自定义排序,例如:
objs = sorted(list(queryset), key=lambda x: my_ids.index(x.id))
编辑:Willem 的回答用 case
做了奇怪的事情,可能比这更快,但如果你关心速度,我仍然不想以任意顺序获取东西。
它确实不关心顺序,因为查询看起来像:
SELECT model.*
FROM model
WHERE model.pk <b>IN (3, 2, 1, 42)</b>
数据库可以return 以任何顺序排列值。根据您使用的数据库、索引机制等,顺序可以是 "deterministic",但甚至有可能 return 记录完全随机。
你可以订购这些,用一个相当复杂的表达:
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(
*[<b>When(pk=pk, then=Value(i)) for i, pk in enumerate(my_ids)</b>],
output_field=IntegerField()
)<b>.asc()</b>
)
这仍然是一个QuerySet
,可以用于惰性查询目的,但问题仍然是为什么要根据的顺序对元素进行排序主键。通常模型(或相关模型)包含更多 "interesting" 元素排序方式。