Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django Order_(按自定义函数)_Django_Sql Order By_Models - Fatal编程技术网

Django Order_(按自定义函数)

Django Order_(按自定义函数),django,sql-order-by,models,Django,Sql Order By,Models,我在型号roll\u numb中有字段。roll\u numb的值如下所示 070-001 070-007 070-343 080-002 080-008 当我按roll\u numb排序时,排序与上面一样。 我想按-分割卷号并按剩余部分排序。(即001、002、008) 代码 我认为在Django的ORM范围内,通过model方法订购queryset是不可能的 因此,为了按照自定义方法对queryset进行排序,我推荐两种方法: 首先 qs = mymodel.objects.all() q

我在型号
roll\u numb
中有字段。
roll\u numb
的值如下所示

070-001
070-007
070-343
080-002
080-008
当我按
roll\u numb
排序时,排序与上面一样。 我想按
-
分割卷号并按剩余部分排序。(即001、002、008)

代码
我认为在Django的ORM范围内,通过
model
方法订购
queryset
是不可能的

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

首先

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

向模型中添加另一个字段,以便使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)

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

from django.db.models.functions import Substr

YourModel.objects.annotate(roll_split=Substr('roll_numb', 5)).order_by('roll_split')
如果希望始终订购模型,只需将该注释移动到模型的管理器:

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

可以有两个字段而不是一个字段。一个字段存储值的第一部分,第二个字段存储值的最后一部分。通过这种方式,您仍然可以轻松地使用Meta。然后,在渲染过程中引入连字符。我是否应该删除
类Meta中的
排序
?是的,只要管理员自己负责排序。另外,根据您使用的数据库后端,可能有一种更方便的方法来拆分
roll\u numb
字段(如PostgreSQL的
split\u part()
)。第一种解决方案应该是
key=
,而不是
key:
。谢谢非常非常好的主意第二个解决方案,谢谢!
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()