按名称和数字 Django 排序

Order by name with number Django

我在 sqlite 数据库中有大约 500 个设备对象,其中有一个 name 字段,例如:

Device-0
Device-1
Device-2
Device-3
...
...
Device-500

当用 django 列出这些时,我希望它根据名称中分号后的数字列出,如上所示。

我试过了:

queryset = Device.objects.all().order_by('name')

也来自这个question

queryset = Device.objects.annotate(int_sort=Cast("name", IntegerField())).order_by("int_sort", "name")

这两个都会产生这个结果:

Device-0
Device-1
Device-10
Device-100
Device-101
...

如有任何帮助,我们将不胜感激。

您正在寻找 "natural sort" ("dictionary sort") order

这不是 SQLite 的内置功能(也不是我所知道的任何其他数据库)。

如果您的所有行都遵循 XYZ-123 格式,您可以

  • 添加一个 .extra() where= 列,其中的表达式用破折号分隔该列,然后将第二部分转换为数字
  • 然后 order_by 那一列。

例子

这是一个示例,您可以在 SQLite 运行 中 shell:

sqlite> create table device (name text);
sqlite> insert into device (name) values ('Device-1'),('Device-2'),('Device-3'),('Device-4'),('Device-5'),('Device-6'),('Device-7'),('Device-8'),('Device-9'),('Device-10'),('Device-11'),('Device-12'),('Device-13'),('Device-14'),('Device-15'),('Device-16'),('Device-17'),('Device-18'),('Device-19'),('Device-20'),('Device-21'),('Device-22'),('Device-23'),('Device-24'),('Device-25'),('Device-26'),('Device-27'),('Device-28'),('Device-29'),('Device-30'),('Device-31'),('Device-32'),('Device-33'),('Device-34'),('Device-35'),('Device-36'),('Device-37'),('Device-38'),('Device-39');
sqlite> select * from device order by name limit 10;
Device-1
Device-10
Device-11
Device-12
Device-13
Device-14
Device-15
Device-16
Device-17
Device-18
sqlite> select *, cast(substr(name,instr(name, '-')+1) as number) number from device order by number limit 10;
Device-1|1
Device-2|2
Device-3|3
Device-4|4
Device-5|5
Device-6|6
Device-7|7
Device-8|8
Device-9|9
Device-10|10

对于这个例子,你应该(但我没有验证,因为我手头没有合适的 Django 应用程序)能够做到

Device.objects.all().extra(
  select={'device_number': "cast(substr(name,instr(name, '-')+1) as number)"},
  order_by='device_number',
)