2009-04-15 79 views
1

我有一個模型,在其Meta類下有一個排序字段。當我執行查詢並取回模型的QuerySet時,它按指定的順序。但是,如果我有列表中的此模型的實例並在列表上執行排序方法,那麼順序與我想要的順序不同。有沒有辦法對模型的實例列表進行排序,使得順序與模型定義中指定的順序相同?如何以相同的方式訂購列表QuerySets在Django中訂購?

回答

3

不是自動的,但有一些工作,是的。您需要定義一個比較器函數(或模型類上的方法),以便根據相關屬性比較兩個模型實例。例如:對卡爾的回答

class Dated(models.Model): 
    ... 
    created = models.DateTimeField(default=datetime.now) 

    class Meta: 
    ordering = ('created',) 

    def __cmp__(self, other): 
    try: 
     return cmp(self.created, other.created) 
    except AttributeError: 
     return cmp(self.created, other) 
+0

+1很好的解決方案,可以在模型級別保持排序,因此無論列表排序完成的位置如何,它都可以被透明地遵守。 – 2009-04-16 13:54:58

3

您的問題的答案是不同程度的是,有一些手動要求。如果list你的意思是已經被一些複雜的查詢形成,那麼,肯定有queryset

queryset.order_by(ClassName.Meta.ordering) 

queryset.order_by(instance._meta.ordering) 

queryset.order_by("fieldname") #If you like being manual 

如果你不工作一個查詢集,那麼當然你仍然可以排序,就像任何人在Python中排序複雜對象一樣:

  • 比較
  • 指定鍵
  • 裝飾/排序/去除裝飾

See the python wiki for a detailed explanation of all three.

2

大廈,你可以很容易地添加使用的所有排序字段,甚至檢測是按照相反的順序者的能力。

class Person(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 
    birthday = date = models.DateField() 

    class Meta: 
    ordering = ['last_name', 'first_name'] 

    def __cmp__(self, other): 
    for order in self._meta.ordering: 
     if order.startswith('-'): 
     order = order[1:] 
     mode = -1 
     else: 
     mode = 1 
     if hasattr(self, order) and hasattr(other, order): 
     result = mode * cmp(getattr(self, order), getattr(other, order)) 
     if result: return result 
    return 0 
+0

非常好。最好把它放到`models.Model`的子類中,這樣你就可以在整個模型中使用它。 – Tom 2011-02-02 11:56:16