Как выполнить естественную сортировку набора запросов с помощью Postgres и SQLite

У меня следующая модель:

from django.db import models

class VersionInfo(models.Model):
    version = models.CharField("Version", max_length=16)  # 3-digit version like "1.2.3".

Мне нужно естественным образом отсортировать QuerySet по 3 частям «version» при рендеринге таблицы django_tables2. Я уже пробовал подобные вещи, но это не сортирует так, как ожидалось:

from django.db.models import Func, IntegerField, Value
from django.db.models.functions import Cast

class SplitPart(Func):
    function = 'SUBSTR'
    template = "%(function)s(%(expressions)s)"

class VersionInfoListView(LoginRequiredMixin, PermissionRequiredMixin, SingleTableMixin, FilterView):

    def get_queryset(self):
        qs = super().get_queryset()
        # noinspection PyUnresolvedReferences
        if not self.request.user.is_sys_admin():
            qs = qs.filter(is_approved=True)

        qs = qs.annotate(
            major=Cast(SplitPart('version', 1, Func('version', Value('.'), function='INSTR') - 1), IntegerField()),
            minor=Cast(
                SplitPart(
                    'version',
                    Func('version', Value('.'), function='INSTR') + 1,
                    Func(SplitPart('version', Func('version', Value('.'), function='INSTR') + 1), Value('.'), function='INSTR') - 1,
                ),
                IntegerField(),
            ),
            patch=Cast(
                SplitPart(
                    'version',
                    Func(SplitPart('version', Func('version', Value('.'), function='INSTR') + 1), Value('.'), function='INSTR')
                    + Func('version', Value('.'), function='INSTR')
                    + 1,
                ),
                IntegerField(),
            ),
        ).order_by('major', 'minor', 'patch')

Да, это очень уродливо, но должно работать в SQLite и Postgres (в SQLite нет функции STRING_TO_ARRAY), но не работает. Есть ли у кого-нибудь идеи? Есть ли библиотека, предоставляющая такую функциональность?

Вернуться на верх