我试图在Django中设计论坛帖子。用户可以发布线程,回复线程或回复其他线程回复(如Reddit评论中)。所有帖子都分享了日期和作者等基本信息,所以我想我要做一个抽象的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
对象都会有一个浪费的关系,因为从功能上来说,它只能是对Thread
或ThreadReply
的回复。
答案 0 :(得分:0)
感谢达伦斯的评论,我调查了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)
Now Post用于线程回复,线程本身只是扩展它。邮政有一个多态的父母'可以接受Thread
或Post
的关系。