I have field in model roll_numb
. Theroll_numb
has values as follows.
070-001
070-007
070-343
080-002
080-008
When
I think it is not possible to order a queryset
by method of model
in Django's ORM scope.
So in order to sort your queryset
by your custom method, I recommend 2 ways:
First
qs = mymodel.objects.all()
qs = sorted(qs, key: lambda i: i.roll_numb().split('-')[1])
Second
Add another field to your model, so enable Django's ORM to sort by the desired value:
MyModel(models.Model):
class Meta:
ordering = ['roll_numb_splitted']
roll_numb_splitted = models.Charfield(max_length=3)
def save(self, *args, **kwargs):
# this is a check to run once
if not self.pk:
self.roll_numb_splitted = self.roll_numb().split('-')[1]
return super(MyModel, self).save(*args, **kwargs)
Annotate your queryset with a custom field:
from django.db.models.functions import Substr
YourModel.objects.annotate(roll_split=Substr('roll_numb', 5)).order_by('roll_split')
If you want to always have your models ordered, just move that annotation to the model's manager:
class YourModelManager(models.Manager):
def get_queryset(self):
qs = super(YourModelManager, self).get_queryset()
return qs.annotate(roll_split=Substr('roll_numb', 5)).order_by('roll_split')
class YourModel(models.Model):
objects = YourModelManager()