[英]How can I order a QuerySet in Django by a charfield with numbers?
我想通过一个带有数字的字符域来订购一个 QuerySet。 我有这个代码:
MyTable.objects.all().order_by('my_char_field')
有一些“my_char_field”的例子:
"ver3", "ver10", "x5.1 (1)", "ver4", "x5.1 (2)"
上面代码的排序结果是:
"ver10", "ver3", "ver4", "x5.1 (1)", "x5.1 (2)"
但我想要的顺序是:
"ver3", "ver4", "ver10", "x5.1 (1)", "x5.1 (2)"
我怎样才能得到自然顺序?
这似乎更像是一个数据存储问题。 如果你改变你的数据结构会变得容易得多
version_type = models.CharField()
version_num = models.FloatField()
version_revision = models.SmallIntegerField(null=True)
unique_together = [('version_type', 'version_num', 'version_revision')]
.order_by('version_type', 'version_num', 'version_revision')
这也将解决您的下一个问题“我如何有效地获得所有版本的 'ver' 类型?”
虽然可以在客户端获取并进行排序,但您也可以使用Substr函数在服务器端执行此操作。
from django.db.models.functions import Substr
MyTable.objects.all().order_by(Substr('my_char_field',3))
更新:
当问题再次更新时,我正在对答案进行另一次更新!! 以下内容并不完整,但您可以在此基础上进行构建。
MyTable.objects.annotate(
sort_field=Case(
When(my_char_field__start_with='ver', Then=Substr(my_char_field, 3)),
When(my_char_field__start_with='x', Then=Substr(my_char_field, 1)),
default=my_char_field,
)
).order_by('sort_field')
您还需要使用 Cast 函数将 sort_field 转换为 int。 这将是一个很长的查询!!
例如,我有一个带有名称字段的 CharField,它具有混合(整数+字符串)值。 “a1”、“f65”、“P”、“55”等..
通过使用 sql cast(用 postgres 和 mysql 测试)解决了这个问题,首先,我尝试按投射的整数值排序,然后按 name 字段的原始值排序。
parking_slots = ParkingSlot.objects.all().extra(
select={'num_from_name': 'CAST(name AS INTEGER)'}
).order_by('num_from_name', 'name')
这样,无论如何,正确的排序对我有用。
正如@AKS 提到的,在内存中进行排序可能效率低下。 只要你有一个大表,你只想拉出排序结果的第一页。 然后,您必须先从数据库中提取每一行,然后才能进行排序。
Something From Vem3456 to Vem6543
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.