Django Order_BY custom function

隐身守侯 提交于 2019-12-23 11:59:10

问题


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 order_by roll_numb the sorting is as it is above. I want to split the roll_numb by - and sort by the remainder. (i.e. 001, 002, 008)

Code

class Meta:
        ordering = ['roll_numb']

回答1:


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)



回答2:


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()


来源:https://stackoverflow.com/questions/34559094/django-order-by-custom-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!