django - 在 Django 中,如何以任意非字母顺序通过多项选择 CharField 进行排序?

标签 django django-models sql-order-by

想象一个模型 Shirtssize CharField,其值仅限于少数选择,例如“小”、“中”、“大”、“超大”等。

要按尺寸对衬衫进行分组,您可以:

Shirts.objects.order_by('size')

但是 Django 会(自然地)按字母顺序对组进行排序,即“大”然后“中”然后“小”然后“超大”。我想要的是在“大”之前的“中”之前有“小”等。

IE。我自然想做的是类似于以下伪代码:
size_order = {'small': 1, 'medium': 2, 'large': 3, 'xlarge': 4}
Shirts.objects.order_by('size_order[size]')

实现这一目标的最佳方法是什么?

编辑:有关各种建议方法的想法,请参阅我对下面答案的评论。我偶然发现了一种使用我正在调查的 SQL ORDER BY CASE 语法的自定义 Manager/QuerySet 方法。

最佳答案

我想出了最接近我正在寻找的东西,那就是使用 QuerySet.extra()利用 SQL 的 CASE WHEN/THEN 语法的方法,Django 不直接支持该语法:

CASE_SQL = '(case when size="small" then 1 when size="medium" then 2 when size="large" then 3 when size="xlarge" then 4 end)' 
Shirt.objects.extra(select={'shirt_order': CASE_SQL}, order_by=['shirt_order'])

鉴于我的(人工)示例,这可能看起来有点矫枉过正和/或肮脏,但这是我正在寻找的技巧!感谢大家对这个问题的其他完全有效的方法,这在某种程度上间接地激发了我想出这种方法。

附言通过 SQL 的 CASE WHEN/THEN 语法创建一个自定义模型 Manager/QuerySet 组合,为这种自定义排序提供更 native 的 Django 接口(interface)是很诱人的,但我将把它作为自己的家庭作业留待下一次!

注意:CASE WHEN/THEN 的语法是特定于数据库的。上面的语法适用于 SQLite。对于 PostgreSQL,省略括号并使用转义单引号而不是双引号。

关于django - 在 Django 中,如何以任意非字母顺序通过多项选择 CharField 进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11695994/

相关文章:

python - 垃圾邮件机器人使我的日志文件困惑 [Django]

python - 如何在 Django 模型上将月份表示为字段

python - Django:ManyToMany 能够排序并添加/删除关系?

python - 更改 django-rest-auth 中的错误消息

python - Django:在Docker上连接到PostgreSQL DB时出现OperationalError

python - "Upload"来自 django shell 的文件

python - 在 django api 调用中检索 UNIX TIMESTAMP

MySQL Ordering a query - 进一步的问题

mysql 更新查询 : add a table column with values

sql - 将 NULL 值排序到表的末尾