2009-08-12 31 views
1

遞歸多對多關係的「到」模型假設下面的模型:訂貨上的場中在Django

class Category(models.Model): 
    related = models.ManyToManyField('self', symmetrical = False, through = 'CategoryRelation', null = True, blank = True) 

假設「到」關係以下中間體:

class CategoryRelation(models.Model): 
    source = models.ForeignKey('Category', null = False, blank = False, verbose_name = _('source'), related_name = 'relation_source') 

    target = models.ForeignKey('Category', null = False, blank = False, verbose_name = _('target'), related_name = 'relation_target') 

    order = models.PositiveIntegerField(_('order'), null = False, blank = True, default = 0) 

    class Meta: 
     ordering = ('order',) 

我怎樣才能獲取與給定類別相關的Category對象,同時保持排序?使用.distinct()即使下面的代碼將產生正確的類別對象,而不是在正確的順序,以及包括在查詢中設置重複的條目:

relations = CategoryRelation.objects.filter(source = self) 

Category.objects.filter(relation_target__in = relations).order_by('related') 

回答

4

以下作品正確排序,但不漏掉重複的條目:

relations = CategoryRelation.objects.filter(source = self) 

Category.objects.filter(relation_target__in = relations).order_by('relation_target') 

調用.distinct()不會有所作爲,因爲之後應用了.order_by()邏輯。但是,在這種情況下,可以利用順序是正整數字段的事實,並且使用relation_target字段的order字段的Min值對每個Category進行註釋,並使用此新的註釋字段進行排序:

return Category.objects.filter(relation_target__in = relations).annotate(relation_target_order = models.Min('relation_target__order')).order_by('relation_target_order') 

這是幾乎完成,但由於此查詢的語義本質使其具有唯一性,這將是明智調用.distinct(),以確保公正的鮮明標誌是真,這樣與其他不同的查詢後組合可以發生:

return Category.objects.filter(relation_target__in = relations).annotate(relation_target_order = models.Min('relation_target__order')).order_by('relation_target_order').distinct() 

在這種情況下.distinct()不影響絲毫的查詢,但ENS那個db/models/sql/query.py方法合併(self,rhs,connector)通過它的斷言:

assert self.distinct == rhs.distinct, \ ...