按特定顺序对带有浮点值的查询集进行排序(例如软件版本)

时间:2019-05-16 12:38:13

标签: python django

我正在使用django,希望得到您的帮助,以便按我的意愿对查询集进行排序。我的查询集从模型中获取版本列表。

这是我的查询集:

def actual_edition():
    return MyModel.objects.values_list('version', flat=True).filter(smt__isnull=False, published=True).order_by('version').first()

它给了我

<QuerySet ['10.0', '9.10', '9.8', '9.9']>

但是我想处理我的queryset以便按以下顺序显示结果:

<QuerySet ['9.8', '9.9', '9.10', '10.0']>

version字段是我模型中的CharField(例如,我不能将其更新为FloatField)。 我找不到使用Django的方法。有什么想法吗?

谢谢!

4 个答案:

答案 0 :(得分:1)

假设您使用的是postgres,则可以使用string_to_array。此question here解决了其中的SQL部分。

对于Django,您需要自定义Func

from django.db.models import Func
class StringToArray(Func):
    template = "%(function)s(%(expressions)s, '.')"
    function = 'string_to_array'

然后您的QuerySet如下:

MyModel.objects.filter(
    smt__isnull=False,
    published=True,
).annotate(
    version_array=StringToArray('version'),
).order_by('version_array').values_list('version', flat=True).first()

答案 1 :(得分:0)

可以使用lambda函数吗?

如果s是浮点数的字符串列表,则

s.sort(key = lambda x:float(x))

应该按照您想要的方式进行排序。

答案 2 :(得分:0)

鉴于您正在存储版本号,您是否考虑过使用字典编排排序?如果您使用零填充存储数字,则可以使用已经使用的确切过滤器(即['09.08', '09.09', '09.10', '10.00'])得到所需的答案

答案 3 :(得分:0)

我找到了正确的语法来做到这一点:

def actual_edition():
    x = list(MyModel.objects.values_list('version', flat=True).filter(smt__isnull=False, published=True).order_by('version'))
    x.sort(key=lambda s: list(map(int, s.split('.'))))

它给了我

# Before sort
['10.0', '10.1', '9.10', '9.8', '9.9']
# After sort
['9.8', '9.9', '9.10', '10.0', '10.1']