I have a Django model with a release_version char field that stores version information in the format 1.1.1 (e.g., 1.2.3). I need to sort a queryset based on this version field so that versions are ordered correctly according to their major, minor, and patch numbers.
class Release(models.Model):
file_name = models.CharField(max_length=255)
release_version = models.CharField(max_length=16)
Using the default order_by gives the result in lexicographic order and it sorts 1.10.0 before 1.2.0 when sorting ascending. The solution seems to be that I can annotate the major, minor and patch version and then sort based on these three fields. The issue in this is that I am not able to figure out how to separate this version into major, minor and patch numbers. I am using postgresql.
To properly sort release_version
field, you can break it down into major
, minor
, and patch
numbers and sort them accordingly.
You can achieve this by using Django's annotate()
feature, which allows you to annotate fields to perform operations on them, and SplitPart
from PostgreSQL, which can split strings based on a delimiter.
This is the code example.
from django.db.models import F, Value
from django.db.models.functions import Cast
from django.db.models.expressions import Func
from django.db.models import IntegerField
queryset = Release.objects.annotate(
major=Cast(Func(F('release_version'), Value('.'), Value(1), function='split_part'), IntegerField()),
minor=Cast(Func(F('release_version'), Value('.'), Value(2), function='split_part'), IntegerField()),
patch=Cast(Func(F('release_version'), Value('.'), Value(3), function='split_part'), IntegerField())
).order_by('major', 'minor', 'patch')
I hope this will solve your issue.