在Django模型上定义排序键

时间:2017-01-17 10:25:33

标签: python django sorting

我有两个Django模型,其中一个指的是另一个。我希望能够基于第一个模型对第二个模型进行排序。我认为下面的代码示例说明了我想要实现的目标。

class Record(models.Model):
    uuid = models.CharField(max_length=32)
    code = models.CharField(max_length=32)

    class Meta:
        ordering = ['code']

class Article(models.Model):
    code = models.CharField(max_length=32)

    def get_sorted_submodels(self):
        return sorted(self.submodels.all(), key=Submodel.key_sorting)

class Submodel(models.Model):
    code = models.CharField(max_length=32)
    article = models.ForeignKey(Article, related_name='submodels')
    record_uuid = models.CharField(max_length=32)

    @property
    def record(self):
        return Record.objects.get(uuid=self.record_uuid)

    @staticmethod
    def key_sorting(obj):
        return (obj.record, obj.code)

如果我现在调用方法get_sorted_submodels,我会收到以下错误:

TypeError: unorderable types: Record() < Record()

我已经在模型Record上实现了字段排序。

  1. 如何使此模型可订购,以便我可以使用此排序 机制?
  2. 如果那是不可能的,还有另一种好办法吗? 首先在Record上进行排序,然后在自己的代码上进行排序?
  3. PS:我明确地不想在Submodel类上使用class Metaordering,因为这基本上是仅在此上下文中使用的第二个排序。

2 个答案:

答案 0 :(得分:2)

ordering元字段仅控制记录在数据库查询中的排序方式sorted是一个Python函数,与此完全无关。

要在Python中对Record实例进行排序,可以为它们提供__lt__方法:

def __lt__(self, other):
    return self.code < other.code

现在Python可以对它们进行排序,你的错误就会消失。但最好让数据库这样做,所以不要使用sorted

def get_sorted_submodels(self):
    return self.submodels.order_by('record__code')

编辑:在编辑后执行此操作,我将更改方法(从django.utils.decorators导入cached_property):

@cached_property
def record(self):
    return Record.objects.get(uuid=self.record_uuid)

@staticmethod
def key_sorting(obj):
    return (obj.record.code, obj.code)

答案 1 :(得分:1)

如果您只想在某些情况下使用此顺序,则可以在选择记录的任何位置指定它。这应该有效:Submodel.objects.all().order_by('submodels', 'record__name')

如果您需要在许多不同的地方使用此自定义订购,您可以考虑制作自定义模型管理器。