Python 我如何在Django通过带有数字的charfield订购QuerySet?
我想按charfield订购一个包含数字的查询集。 我有以下代码:Python 我如何在Django通过带有数字的charfield订购QuerySet?,python,django,django-queryset,Python,Django,Django Queryset,我想按charfield订购一个包含数字的查询集。 我有以下代码: MyTable.objects.all().order_by('my_char_field') 这里有一些“我的字符字段”的示例: 带有上述代码的订单结果为: "ver10", "ver3", "ver4", "x5.1 (1)", "x5.1 (2)" 但我想要的顺序是: "ver3", "ver4", "ver10", "x5.1 (1)", "x5.1 (2)" 如何获取自然顺序?虽然可以在客户端获取并进行排序,但也
MyTable.objects.all().order_by('my_char_field')
这里有一些“我的字符字段”的示例:
带有上述代码的订单结果为:
"ver10", "ver3", "ver4", "x5.1 (1)", "x5.1 (2)"
但我想要的顺序是:
"ver3", "ver4", "ver10", "x5.1 (1)", "x5.1 (2)"
如何获取自然顺序?虽然可以在客户端获取并进行排序,但也可以在服务器端使用该函数进行此操作
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_字段强制转换为int。这将是一个很长的查询 虽然可以在客户端提取并进行排序,但也可以在服务器端使用该函数进行此操作
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_字段强制转换为int。这将是一个很长的查询 这更像是一个数据存储问题。如果您更改了数据结构,这将变得容易得多
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'类型?”这似乎更像是一个数据存储问题。如果您更改了数据结构,这将变得容易得多
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'类型?”正如@AKS所提到的,在内存中进行排序可能效率低下。一旦你有一个大的表,你想拉只排序结果的第一页。然后,您必须从数据库中提取每一行,然后才能进行排序。
也许您可以尝试添加另一个字段,该字段在添加新记录时从“排序”字段填充。这一次,您可以让数据库排序为您工作
从Vem3456到Vem6543的内容
正如@AKS所提到的,在内存中进行排序可能效率低下。一旦你有一个大的表,你想拉只排序结果的第一页。然后,您必须从数据库中提取每一行,然后才能进行排序。
也许您可以尝试添加另一个字段,该字段在添加新记录时从“排序”字段填充。这一次,您可以让数据库排序为您工作
从Vem3456到Vem6543的内容
我有一个带有名称字段的CharField,例如,它有混合(int+string)值。“a1”、“f65”、“P”、“55”e.t.c
通过使用sql cast(使用postgres和mysql测试)解决了这个问题,
首先,我尝试按强制转换的整数值排序,然后按名称字段的原始值排序
parking_slots = ParkingSlot.objects.all().extra(
select={'num_from_name': 'CAST(name AS INTEGER)'}
).order_by('num_from_name', 'name')
这样,在任何情况下,正确的排序对我来说都是有效的。我有一个带有名称字段的CharField,例如,它有混合(int+string)值。“a1”、“f65”、“P”、“55”e.t.c 通过使用sql cast(使用postgres和mysql测试)解决了这个问题, 首先,我尝试按强制转换的整数值排序,然后按名称字段的原始值排序
parking_slots = ParkingSlot.objects.all().extra(
select={'num_from_name': 'CAST(name AS INTEGER)'}
).order_by('num_from_name', 'name')
这样,在任何情况下,正确的排序对我都有效。它总是以
ver
开头吗?这些是唯一的变体吗?该字符字段是否总是以数字系列结尾,以字母系列开头?版本内部是否有点,例如版本2.1.2
?@AKS版本内部可能有点,不同的开始和结束请用完整的示例更新您的问题。很难猜测它可能有什么选择。我甚至不确定是否可以在查询端执行此操作。您是否可以在帖子中提及它拥有或可能拥有的所有可能配置,以及您对这些情况的首选预期顺序?它是否总是以ver
开头?这些是唯一的变体吗?该字符字段是否总是以数字系列结尾,以字母系列开头?版本内部是否有点,例如版本2.1.2
?@AKS版本内部可能有点,不同的开始和结束请用完整的示例更新您的问题。很难猜测它可能有什么选择。我甚至不确定是否可以在查询端执行此操作。您是否可以在帖子中提及所有可能的配置,以及您对这些情况的首选预期顺序?我确定您没有查看更新的帖子?而且,这对10
不起作用,因为它是字符串。我没有看到更新就写了这个答案。我想我必须添加一个更新。@Sayse对这个问题做了太多的编辑,但是新的更新应该会在轨道上获得OP是的@aks从这个意义上说,新添加的答案是正确的耶@Sayse,需要做很多工作。你的答案肯定是正确的,我投了更高的票,OP应该接受你的答案是正确的。我肯定你没有看更新的帖子?而且,这对10
不起作用,因为它是字符串。我没有看到更新就写了这个答案。我想我必须添加一个更新。@Sayse对这个问题做了太多的编辑,但是新的更新应该会在轨道上获得OP是的@aks从这个意义上说,新添加的答案是正确的耶@Sayse,需要做很多工作。你的答案肯定是正确的,我投了赞成票,OP应该接受你的答案。