Python Django模型继承与管理系统

Python Django模型继承与管理系统,python,django,django-models,django-admin,Python,Django,Django Models,Django Admin,我正在尝试构建一个系统来管理页面中各种类型的内容。例如,页面可能包含文本内容、超链接内容、视频内容等 在我的建模代码中,我有一个基类: class ContentItem(models.Model): title = models.CharField(max_length=1000) page_order = models.IntegerField() last_update_date = models.DateTimeField(default=datetime.now

我正在尝试构建一个系统来管理页面中各种类型的内容。例如,页面可能包含文本内容、超链接内容、视频内容等

在我的建模代码中,我有一个基类:

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']
这是所有内容项的基类。页面顺序控制其在页面上的位置,例如页面顺序为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。它们将按页面顺序排序,以确定呈现模板时它们在页面上的顺序

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()
我知道这是可行的,但我确定页面上对象位置的方案变得更加困难。我需要遍历所有内容关系,按页面顺序排序,然后呈现它们

我认为在这两种情况下,我都希望在基类上声明一个render()方法,每个特定的内容类型都可以继承该方法。这样,如果我有一个ContentItems列表,我可以使用duck类型来呈现它们,而不用担心它们的特定类型

我的最后一个问题是,我如何用这个让管理场所变得更好?我怎样才能轻松地在一个视图中查看构成页面的所有内容项,以便通过更改页面顺序轻松地移动它们


感谢您阅读本文,如果您需要更多信息,请告诉我。

这是一个很好的方法。不幸的是,Django的ORM不能像您希望的那样顺利地处理模型继承<代码>页面。内容将包含
内容
对象的查询集。如果要访问子类型,则需要创建某种向下转换内容对象的方法。问题是,这需要对每个对象进行查询,这可能会很快失控。描述一种在幕后使用
select\u related()
在一个查询集中获取混合子类型的技术

谢谢@jcdayer。这是非常有用的信息。但有一件事我还不清楚,那就是我将如何在管理界面中实现这一点。理想情况下,我希望有一种方法来列出页面的内容,并有适当的管理形式显示为基于特定类的项目。例如,如果一个页面的contents属性中有2个LinkContents和1个TextContent,我希望前两个可以用Link表单编辑,另一个可以用text表单编辑。有没有一个简单的方法来做这样的事情?我做过很多管理定制,但从未见过这样的事情。