Django模型继承和管理系统

发布于 2024-10-25 21:51:54 字数 1805 浏览 5 评论 0原文

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

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

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 轻松地移动它们?

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

I'm trying to build a system for managing the various types of content in a page. For example, a page may have text content, hyperlink content, video content, ect.

In my modeling code, I have a base class:

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']

This is the base class for all content items. The page order controls what position it is on the page, for example the item with page_order = 0 should be at the top of the page. Next I define a few specific content models that inherit from this one.

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')

There could be many more such content types. Then I would define a Page model that is composed of all the various content types. Ideally, I could put all the types in on relation based on the base type. So in this one relation you would have a mixture of LinkContents, TextContents, and VideoContents. They would be sorted by page_order to determine their order on the page when rendering the template.

class Page(models.Model):
  contents = models.ManyToManyField(ContentItem)
  title = models.CharField()

Is there any way to make such a scheme work? Or is it problematic to have one relation with different types of models in it? I know this is a good solution from and object oriented programming standpoint, basically using polymorphism to my advantage, but I am not sure it makes sense at the database level.

Do I instead need something more like this:

class Page(models.Model):
  video_contents = models.ManyToManyField(VideoContent)
  link_contents = models.ManyToManyField(LinkContent)
  text_contents = models.ManyToManyField(TextContent)
  title = models.CharField()

I know this would work, but my scheme of determining the placement of the objects on the page becomes more difficult. I would need to traverse all the content relations, sort them by page_order and then render them.

I think in both cases, I want to declare a render() method on the base class that each specific content type can inherit. This way if I have a list of ContentItems I can use duck typing to render them without worrying about their specific type.

My final question is how do I make admin place nice with this? How would I make an easy way to see all of the ContentItems that make up a page in one view, so they can easily be moved around by changing page_order?

Thanks for reading of this, let me know if you need more information.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光病人 2024-11-01 21:51:54

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

This is a fine way to do it. Unfortunately, Django's ORM doesn't handle model inheritance as smoothly as you might want. page.contents will contain a QuerySet of Content objects. If you want to access the subtypes, you need to create some way of downcasting a content object. The problem is that this requires an query per object, which can rapidly get out of hand. This blog post describes a technique for getting the mixed subtypes in one queryset, using select_related() behind the scenes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文