【问题标题】:Django: Example of generic relations using the contenttypes framework?Django:使用内容类型框架的通用关系示例?
【发布时间】:2013-06-01 22:18:31
【问题描述】:

我已经多次仔细研究过有关内容类型框架的 Django 文档,但我对它的理解还不够好,无法在我的项目中实现通用关系。我一直在寻找有关此事的在线示例或教程,但我找不到一个。叫我笨蛋,但我需要一些帮助(请不要通过简单地链接到文档来回答)。基于网上资源的缺乏,我相信如果你用一个完整的例子来回答这个问题,你的回答可能是迄今为止关于 django 泛型关系的最有用的网上例子(奖金!)。

所以,我的问题是:有人可以展示一个简单的模型示例,或者几行代码来展示如何与通用模型的实例进行交互吗?


作为灵感,以下是我认为很常见的情况:

网站的媒体项目在很大程度上被视为相同,但略有不同。例如,假设有图像和视频项目,用户可以“喜欢”项目或对项目“评论”。无论是发布在图像还是视频项目上,点赞和 cmet 都应该被同等对待。因此,如果有一个 ItemView 用于查看用户相册中的图像或视频,则可以进行以下类型的调用:mediaitem.comments.all()len(mediaitem.likes.all())comment.user_who_commented,而不必知道它是哪种媒体项是(图像或视频)。

我相信您需要 六个模型

  • 抽象MediaItem
  • 两种不同类型的媒体项目:ImageItemVideoItem
  • 抽象MediaItemActions
  • 可以对媒体项执行两种不同类型的操作:LikeComment

如果你知道如何使用这个 Django 特性,请给我们一个完整的例子!我觉得这将是一个非常强大的工具,并且渴望在我的应用程序中使用它。越明确越好。

【问题讨论】:

    标签: python django django-models django-contenttypes generic-foreign-key


    【解决方案1】:

    您的用例听起来与(现已弃用)Django comments framework 非常相似。如果您查看models,您将看到如何在BaseCommentAbstractModel 中使用通用关系——注意您需要所有三个字段,ForeignKeyContentType,这是一个保存对象@ 的字段987654327@s 和 GenericForeignKey 字段。

    至于如何通过GenericForeignKey查询对象,你可以在那个项目的template tags看到一些例子。例如参见BaseCommentNode 中的get_query_set 方法,该方法通过查询目标对象的内容类型和pk 来检索cmets。

    def get_query_set(self, context):
        ctype, object_pk = self.get_target_ctype_pk(context)
        if not object_pk:
            return self.comment_model.objects.none()
    
        qs = self.comment_model.objects.filter(
            content_type = ctype,
            object_pk    = smart_text(object_pk),
            site__pk     = settings.SITE_ID,
        )
    

    【讨论】:

      【解决方案2】:

      我的一个项目实际上有一个非常相似的情况,有各种媒体类型。

      class TaggedItem(models.Model):
          tag = models.SlugField()
          content_type = models.ForeignKey(ContentType)
          object_id = models.PositiveIntegerField()
          content_object = generic.GenericForeignKey('content_type', 'object_id') 
      
      class ReviewedItem(models.Model):
          content_type = models.ForeignKey(ContentType)
          object_id = models.PositiveIntegerField()
          content_object = generic.GenericForeignKey('content_type', 'object_id')
          review = models.ForeignKey("Review")
      
      class CreativeWork(models.Model):
        #other fields 
        keywords = generic.GenericRelation("TaggedItem",null=True, blank=True, default=None)
        reviews = generic.GenericRelation("ReviewedItem",null=True, blank=True, default=None)
      
      class MediaObject(CreativeWork):
        #fields
      class VideoObject(MediaObject):
        #fields
      class AudioObject(MediaObject):
        #fields
      

      每个视频或音频都是一个 MediaObject,它是一个 CreativeWork。 CreativeWorks 与标签和评论有 GenericRelation。所以现在任何东西都可以被标记或审查。

      您所需要的只是让“动作”拥有一个指向 ContentType 的 ForeignKey。 比向您的模型添加 GenericRelation。我实际上发现 django.docs 非常有帮助:) 但如果不是希望这会有所帮助。

      【讨论】:

        【解决方案3】:

        另一个选项是Polymorphic Models。我不会说这是你应该走的路,但它可能是一种选择。

        我是通用外键和多态模型的粉丝。多态模型在模型中有很多相似性的情况下效果最好。

        【讨论】:

          猜你喜欢
          • 2014-09-18
          • 2018-06-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-15
          • 2016-09-22
          • 1970-01-01
          • 2018-06-13
          相关资源
          最近更新 更多