繁体   English   中英

如何通过带数字的字符字段在 Django 中订购 QuerySet?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM