2010-06-27 61 views
2

假設我有一個代表現實生活中物體的幾個型號:「」,「主席」,「室」整蠱Django的GenericRelation查詢

我也有一個「集合」的模式,它代表了這些模型的一些記錄集合。

每個模型都可以是多個集合的成員 - 因此,我還創建了一個「成員」模型,它表示一個對象是集合的成員。它的定義如下:

class Membership(models.Model): 
    content_type = models.ForeignKey(ContentType) 
    object_id  = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 

    collection  = models.ForeignKey('Collection', related_name="members") 

我希望能夠創造一個的QuerySet,其給出的集合,代表了其所有成員一個給定的模型。我知道我可以通過編程方式做到這一點,但我需要它在一個QuerySet,它可以過濾,排序等

編輯:

SELECT * FROM 
     (modelx INNER JOIN membership ON modelx.id = membership.object_id) 
    WHERE 
     (membership.collection_id=<my-collection-id> AND  
     membership.content_type_id=<modelx-type-id>) 

顯然,這可以使用原始SQL來完成

但它可以使用Django查詢語言來表示嗎?

回答

2

看來我已經找到了解決方案,通過使用QuerySetextra方法:

def members_of_model(collection,cls): 
    cls_type = ContentType.objects.get_for_model(cls) 
    cm_tablename = CollectionMembership._meta.db_table 
    cls_tablename = cls._meta.db_table 
    return cls.objects.all().extra(tables=[cm_tablename], 
            where=[ '%s.content_type_id=%%s' % cm_tablename, 
              '%s.collection_id=%%s' % cm_tablename, 
              '%s.object_id=%s.id' % (cm_tablename, cls_tablename) ], 
            params=[cls_type.id,collection.id]) 

這將返回一個特定的模型,其中包含它們是一個特定集合成員的所有記錄的有效查詢集。

0

不,這是不可能的。查詢集只能是單一模型類型。因此,您可以獲取Membership對象的查詢集並引用每個對象的content_object屬性,這會爲您提供相關對象,但無法直接在一個查詢集中獲取所有相關對象。

+1

我只希望查詢集舉行一個模型...... 我能改寫這個問題的記錄: 我可以查詢模型X的所有記錄,所以,存在着具有記錄X作爲其內容的會員資格對象和其「集合」字段中的特定集合? – adamk 2010-06-28 06:33:34

1

我實現的正是這種由上自定義管理器with_model方法的會員制模式的方式:

class CollectionMemberManager(models.Manager): 
    use_for_related_fields = True 

    def with_model(self, model): 
     return model._default_manager.filter(pk__in=self.filter(member_content_type=ContentType.objects.get_for_model(model)).values_list('member_object_id', flat=True)) 

CollectionMember是我相當於你Membership模型。有關更多上下文,請參閱the code in its entirety

+0

這是一個有效的答案,只有兩個問題: (1)它確實需要額外的查詢& (2)對於大集合使用pk__in並不總是有效 - 對於大集合(約1000個成員),生成的查詢太長了。 – adamk 2010-06-28 06:35:08