2👍
You’ll need to extract the numbers from the strings. Postgres and mysql provide regexp_replace
function (I’m not sure about other databases). But Django doesn’t provide an implementation, so we’ll write our own function:
from django.db.models import Func, Value
class RegexpReplace(Func):
function = 'REGEXP_REPLACE'
def __init__(self, expression, search, replace, **extra):
search = Value(search)
replace = Value(replace)
super(RegexpReplace, self).__init__(expression, search, replace, **extra)
I’ll assume you want to split the names until the digits at the end, and then you want to sort using this first half, and then the numbers at the end. (This will work fine for you until you start getting 3-digit numbers before the hyphen, i.e. SE99-A1, SE100-A1).
from django.db.models import F, IntegerField
from django.db.models.functions import Cast
qs = ... # get your queryset
qs.annotate(
letters=RegexpReplace(F('name'), '(.*[a-zA-Z])[0-9]+$', r'\1'),
seq=Cast(
RegexpReplace(F('name'), '.*[a-zA-Z]([0-9]+)$', r'\1'),
IntegerField(),
),
).order_by('letters', 'seq')
0👍
Use Substr to separate out the first part of the name from the numbers at the end, and then sort by this new annotation first.
from django.db.models.functions import Substr, Length
qs = qs.annotate(letters=Substr('name', 1, 6), length=Length('name'))
qs = qs.order_by('letters', 'length', 'name')
return qs
- [Django]-How to pass flag to child serializer in DRF
- [Django]-How to use django-ddp
- [Django]-Django: get related objects of related objects and pass to template
- [Django]-How to start a django cms project
- [Django]-Django allauth CSRF Verification fail error
Source:stackexchange.com