Django Order_BY自定义功能

A.J*_*.J. 4 django sql-order-by models

我有模型领域roll_numb.该roll_numb如下具有价值.

070-001
070-007
070-343
080-002
080-008
Run Code Online (Sandbox Code Playgroud)

当我order_by roll_numb的排序是如上所述.我想拆分roll_numb并按-余数排序.(即001,002,008)

class Meta:
        ordering = ['roll_numb']
Run Code Online (Sandbox Code Playgroud)

小智 8

我认为不可能在 Django 的 ORM 范围内订购querysetby 方法model

因此,为了按照您queryset的自定义方法对您进行排序,我推荐两种方法:

第一的

qs = mymodel.objects.all()
qs = sorted(qs, key: lambda i: i.roll_numb().split('-')[1])
Run Code Online (Sandbox Code Playgroud)

第二

将另一个字段添加到您的模型中,以便启用 Django 的 ORM 以按所需值排序:

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)
Run Code Online (Sandbox Code Playgroud)


Ale*_*zov 5

使用自定义字段注释您的查询集:

from django.db.models.functions import Substr

YourModel.objects.annotate(roll_split=Substr('roll_numb', 5)).order_by('roll_split')
Run Code Online (Sandbox Code Playgroud)

如果您希望始终订购模型,只需将该注释移动到模型的管理器:

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()
Run Code Online (Sandbox Code Playgroud)