代码之家  ›  专栏  ›  技术社区  ›  adamk

Django GenericRelation查询

  •  2
  • adamk  · 技术社区  · 15 年前

    假设我有几个模型代表现实生活中的物体:“ 椅子 ", " 房间 "

    我也有一个 “模型,它表示这些模型的一些记录集合。

    每个模型都可以是多个集合的成员-因此,我还创建了一个 会员 表示对象的模型是集合的成员。定义如下:

    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")
    

    我想创造一个 ,它给定了一个集合,表示它的所有成员 给定模型的

    编辑:

    显然,这可以使用原始SQL完成:

       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> )
    

    3 回复  |  直到 15 年前
        1
  •  2
  •   adamk    15 年前

    看来我已经找到了解决办法,通过使用 QuerySet extra

    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] )
    

    这将返回特定模型的有效查询集,该查询集包含作为特定集合成员的所有记录。

        2
  •  1
  •   Joseph Spiros    15 年前

    我通过一个 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 .

        3
  •  0
  •   Daniel Roseman    15 年前

    不,这不可能。查询集只能是一种模型类型。这样你就可以得到 Membership 对象并引用每个对象的 content_object 属性,它将为您提供相关对象,但您不能在一个查询集中直接获取所有相关对象。