Django模型继承与管理系统

Jon*_*Jon 6 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 Meta:
      abstract = True
      ordering = ['page_order', 'last_update_date', 'title']
Run Code Online (Sandbox Code Playgroud)

这是所有内容项的基类.页面顺序控制它在页面上的位置,例如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')
Run Code Online (Sandbox Code Playgroud)

可能会有更多此类内容类型.然后我将定义一个由所有各种内容类型组成的页面模型.理想情况下,我可以根据基类型将所有类型放在关系上.因此,在这个关系中,您将混合使用LinkContents,TextContents和VideoContents.它们将按page_order排序,以确定在呈现模板时页面上的顺序.

class Page(models.Model):
  contents = models.ManyToManyField(ContentItem)
  title = models.CharField()
Run Code Online (Sandbox Code Playgroud)

有没有办法让这样的计划有效?或者与其中的不同类型的模型建立一种关系是否有问题?我知道这是一个很好的解决方案和面向对象编程的立场,基本上使用多态性对我有利,但我不确定它在数据库级别是否有意义.

我是否需要更像这样的东西:

class Page(models.Model):
  video_contents = models.ManyToManyField(VideoContent)
  link_contents = models.ManyToManyField(LinkContent)
  text_contents = models.ManyToManyField(TextContent)
  title = models.CharField()
Run Code Online (Sandbox Code Playgroud)

我知道这会起作用,但我确定页面上对象位置的方案变得更加困难.我需要遍历所有内容关系,按page_order对它们进行排序,然后再渲染它们.

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

我的最后一个问题是如何让管理员这个好看?如何在一个视图中轻松查看构成页面的所有ContentItem,以便通过更改page_order轻松移动它们?

感谢您阅读此内容,如果您需要更多信息,请与我们联系.

jcd*_*yer 3

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