2017-01-17 44 views
0

我有兩個Django模型,其中一個指向另一個。我希望能夠根據第一個模型對第二個模型進行排序。我認爲下面的代碼示例最能說明我想實現的目標。在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() 

我已經實施的現場訂貨型號記錄。

  1. 我該如何使這個模型可訂購,使我可以使用這種排序 機制?
  2. 如果這是不可能的,是否有另一個好方法來 啓用排序上記錄第一,然後在自己的代碼?

PS:我明確不想子模型類使用class Metaordering,因爲這基本上只有在這種情況下使用的第二順序。

回答

1

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左右(進口cached_property方法.decorators):

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

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

我喜歡這個答案。但是,我看到我太簡化了我的例子。我用一個稍微複雜的例子來編輯我的問題。 – physicalattraction

+0

我明白了。如果它實際上不是一個外鍵,但是你手動完成,那麼你不能使用數據庫。現在您的key_sorting函數將不得不檢索記錄。但你可以用@cached_property替換\ @property來保存一些查詢。 – RemcoGerlich

1

如果您只想在某些情況下使用此排序,則可以在選擇記錄的任何位置指定它。這應該工作:Submodel.objects.all().order_by('submodels', 'record__name')

如果您需要在很多不同的地方使用此自定義順序,您可以考慮製作自定義模型管理器。