我正在尝试构建一个系统来管理页面中各种类型的内容。例如,页面可以具有文本内容、超链接内容、视频内容等。
在我的建模代码中,我有一个基类:
class ContentItem(models.Model):
title = models.CharField(max_length=1000)
page_order = models.IntegerField()
last_update_date = models.DateTimeField(default=datetime.now())
class Meta:
abstract = True
ordering = ['page_order', 'last_update_date', 'title']
这是所有内容项的基类。页面顺序控制它在页面上的位置,例如 page_order = 0 的项目应位于页面顶部。接下来我定义了一些继承于此的特定内容模型。
class LinkContent(ContentItem):
url = models.URLField()
link_text = models.CharField(max_lenth=1000)
class TextContent(ContentItem):
text = models.CharField()
class VideoContent(ContentItem):
title = models.CharField()
video_file = models.FieldField(upload_to = 'videos')
可能还有更多这样的内容类型。然后我将定义一个由所有各种内容类型组成的页面模型。理想情况下,我可以将所有类型放入基于基本类型的关系中。因此,在这一关系中,您将拥有 LinkContents、TextContents 和 VideoContents 的混合体。它们将按 page_order 排序,以确定渲染模板时它们在页面上的顺序。
class Page(models.Model):
contents = models.ManyToManyField(ContentItem)
title = models.CharField()
有什么办法可以让这样的计划发挥作用吗?或者与其中不同类型的模型建立一种关系是否有问题?我知道从面向对象编程的角度来看这是一个很好的解决方案,基本上使用多态性来发挥我的优势,但我不确定它在数据库级别是否有意义。
我是否需要更多类似这样的东西:
class Page(models.Model):
video_contents = models.ManyToManyField(VideoContent)
link_contents = models.ManyToManyField(LinkContent)
text_contents = models.ManyToManyField(TextContent)
title = models.CharField()
我知道这会起作用,但是我确定页面上对象的位置的方案变得更加困难。我需要遍历所有内容关系,按 page_order 对它们进行排序,然后渲染它们。
我认为在这两种情况下,我想在每个特定内容类型可以继承的基类上声明一个 render() 方法。这样,如果我有一个 ContentItems 列表,我可以使用鸭子类型来呈现它们,而不必担心它们的特定类型。
我的最后一个问题是如何使管理场所变得更好?我如何创建一种简单的方法来在一个视图中查看构成页面的所有 ContentItems,以便可以通过更改 page_order 轻松地移动它们?
感谢您阅读本文,如果您需要更多信息,请告诉我。