Django QuerySet 按 ID 自定义排序
给定一个 ids/pks 列表,我想生成一个按列表中索引排序的对象的 QuerySet
。
通常我会从以下开始:
pk_list = [5, 9, 2, 14]
queryset = MyModel.objects.filter(pk__in=pk_list)
这当然会返回对象,但是按照模型元排序属性的顺序,并且我希望按照 中的
。pk
的顺序获取记录pk_list
最终结果必须是一个 QuerySet
对象(不是列表),因为我希望将有序的 QuerySet
传递给 Django 的 ModelMultipleChoiceField
表单字段。
Given a list of ids/pks, I'd like to generate a QuerySet
of objects ordered by the index in the list.
Normally I'd begin with:
pk_list = [5, 9, 2, 14]
queryset = MyModel.objects.filter(pk__in=pk_list)
This of course returns the objects, but in the order of the models meta ordering property, and I wish to get the records in the order of the pk
s in pk_list
.
The end result has to be one QuerySet
object (not a list), as I wish to pass the ordered QuerySet
to Django's ModelMultipleChoiceField
form field.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
没有内置的方法可以做到这一点。
如果您使用的是 MySQL,则可以使用该数据库的
FIELD()
函数在模型上设置自定义排序序列,并按该序列进行排序。这会起作用:There isn't a built-in way to do this.
If you're using MySQL, you can use that database's
FIELD()
function to set up a custom ordering sequence on your model, and sort by that. This would work:在 Django 2.2 中,我可以使用以下方法根据订单列表对 QuerySet 进行排序:
In Django 2.2, I was able to order QuerySet based on an order list using following approach:
我不知道如何使用过滤条件来做到这一点。如果您的数据库将按照
IN
子句的顺序返回行,那么您也许能够将 Django 的extra
方法与结合起来ROWNUM 由您的数据库提供来实现此目的。
例如:
其中
row_num()
被假定为返回当前行的行号的数据库函数。 Postgresql 8.4+ 支持row_num()
但我不知道如何使用与IN
子句中的值相同的顺序对返回的行进行排序。我认为更好的方法是子类 ModelMultipleChoiceField 并在渲染时添加自定义排序逻辑。
I do not know of a way to do this using a filter condition. If your database will return the rows in the order of the
IN
clause then you may be able to combine Django'sextra
method with theROWNUM
provided by your database to achieve this.For e.g.:
Where
row_num()
is assumed to be a database function that returns the row number of the current row. Postgresql 8.4+ supportsrow_num()
but I do not know how to order the rows returned using the same order as the values in theIN
clause.I think a better way would be to sub class
ModelMultipleChoiceField
and add custom sorting logic when rendering.