【问题标题】:Django Model - Abstract Class with Self RelationshipDjango 模型 - 具有自我关系的抽象类
【发布时间】:2018-03-13 23:37:18
【问题描述】:

我正在尝试在 Django 中设计一个论坛主题。用户可以发布主题、回复主题或回复其他主题回复(如在 Reddit cmets 中)。所有帖子都共享日期和作者等基本信息,所以我想我会做一个抽象的Post 类。由于所有帖子都可以有他们正在回复的parent 帖子,我的直觉是尝试在抽象类上定义它:

class Post(models.Model):
    content = models.TextField(max_length=1000)
    parent = models.ForeignKey('self', null=True)
    createdBy = models.ForeignKey(User)
    class Meta:
        abstract = True

class Thread(Post):
    title = models.CharField(max_length=200)

class ThreadReply(Post):
    score = models.IntegerField(default=0)

但是结果是子类只能有一个相同类型的父类,而ThreadReply 应该真的可以有一个Thread 的父类或一个ThreadReply 的父类。 一种解决方案是,如果我在 ThreadReply 中定义这两种关系:

class Post(models.Model):
    content = models.TextField(max_length=1000)
    createdBy = models.ForeignKey(User)
    class Meta:
        abstract = True

class Thread(Post):
    title = models.CharField(max_length=200)

class ThreadReply(Post):
    score = models.IntegerField(default=0)
    parentThread = models.ForeignKey(Thread,null=True)
    parentReply = models.ForeignKey(ThreadReply,null=True)

但这感觉还不够……面向对象?困扰我的是每个ThreadReply 对象都会有一个浪费的关系,因为从功能上讲,它只能是回复ThreadThreadReply

【问题讨论】:

  • 是的,泛型关系似乎是这样,谢谢。当我得到它的工作时,我会用我的通用关系解决方案更新帖子。

标签: python django inheritance database-design data-modeling


【解决方案1】:

感谢 Dahren 的评论,我查看了 Generic Relations 并找到了我需要的东西。它确实涉及更改继承,以使父类不再是抽象的:

from django.contrib.contenttypes.fields import GenericForeignKey,GenericRelation
from django.contrib.contenttypes.models import ContentType

class Post(models.Model):
    content = models.TextField(max_length=1000)
    createdBy = models.ForeignKey(User)
    score = models.IntegerField(default=0)
    content_type = models.ForeignKey(ContentType,on_delete=models.CASCADE,null=True)
    object_id = models.PositiveIntegerField(null=True)
    parent = GenericForeignKey(content_type,object_id)
    replies = GenericRelation('Post')

class Thread(Post):
    title = models.CharField(max_length=200)

现在 Post 用于线程回复,线程本身只是对其进行了扩展。 Post 有一个多态的“父”关系,可以接受ThreadPost

【讨论】:

    猜你喜欢
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    相关资源
    最近更新 更多