查询集排序:为 django ORM 查询指定列排序规则
Posted
技术标签:
【中文标题】查询集排序:为 django ORM 查询指定列排序规则【英文标题】:Queryset sorting: Specifying column collation for django ORM query 【发布时间】:2013-09-26 23:02:19 【问题描述】:我开始调查为什么我的 Django Model.objects.filter(condition = variable).order_by(textcolumn) 查询不能以正确的顺序生成对象。发现是数据库(Postgresql)的问题。
在我之前的问题 (Postgresql sorting language specific characters (collation)) 中,我发现(在 zero323 的大力帮助下,我可以真正让它工作)我可以像这样为每个数据库查询指定排序规则:
SELECT nimi COLLATE "et_EE" FROM test ORDER BY nimi ASC;
但据我所知,order_by 只接受字段名称作为参数。
我想知道,是否可以通过某种方式扩展该功能以包含排序规则参数?是否有可能使用 mixins 或诸如此类的东西以某种方式破解它?还是功能请求是目前唯一的方法?
我希望它能像这样工作:
Model.objects.filter(condition = variable).order_by(*fieldnames, collation = 'et_EE')
编辑1: 显然我不是唯一一个要求这个的人: https://groups.google.com/forum/#!msg/django-developers/0iESVnawNAY/JefMfAm7nQMJ
艾伦
【问题讨论】:
如需就如何改进 Django 提出建议,请提交new feature request 和/或在django-developers 上发帖。现在你可能不得不使用raw SQL query。 嗯,是的,谢谢。我想/将要求该功能。我只想先知道,是否可以使用现有工具实现它。毫无疑问,Raw Query 就是其中之一。 【参考方案1】:
由于 Django 1.8 order_by()
不仅接受字段名称but also query expressions。
在another answer 中,我举例说明了如何覆盖列的默认排序规则。这里有用的查询表达式是Func(),您可以继承或直接使用它:
nimi_et = Func(
'nimi',
function='et_EE',
template='(%(expressions)s) COLLATE "%(function)s"')
Test.objects.order_by(nimi_et.asc())
但请注意,生成的 SQL 将更像:
SELECT nimi FROM test ORDER BY nimi COLLATE "et_EE" ASC;
也就是说,排序规则在ORDER BY
子句中被覆盖,而不是在SELECT
子句中。但是,如果您需要在WHERE
子句中使用它,您可以在annotate()
中使用Func()
。
【讨论】:
请注意,在ORDER BY
中设置排序规则会阻止使用任何原本适用的索引。【参考方案2】:
好的。现在看来,原始查询是做到这一点的唯一方法。
但是有 django ticket open 希望很快就会关闭/解决。
【讨论】:
以上是关于查询集排序:为 django ORM 查询指定列排序规则的主要内容,如果未能解决你的问题,请参考以下文章