Django Model Inheritance and Administration System

I am trying to create a system to manage various types of content on a page. For example, a page may contain text content, hyperlink content, video content, etc.

In my simulation 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 elements. The order of the pages determines what position it occupies on the page, for example, an element with page_order = 0 should be at the top of the page. Then I define a few specific content models that inherit from this.

 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 may be many such types of content. Then I would define a page model consisting of all types of content. Ideally, I could put all types depending on the base type. So in this regard you will have a mixture of LinkContents, TextContents and VideoContents. They will 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 circuit work? Or is it problematic to have one relation to the different types of models in it? I know this is a good solution from the point of view of object-oriented programming, mainly using polymorphism in my interests, but I'm not sure if this makes sense at the database level.

Do I need something more:

 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 will work, but my scheme for determining the placement of objects on a page is getting complicated. I will need to go through all the relationships with the content, sort them by page_order and then render.

I think that in both cases I want to declare a render () method for a base class that can inherit every specific type of content. That way, if I have a list of ContentItems, I can use duck print to visualize them without worrying about their specific type.

My last question is: how can I make admin enjoyable with this? How could I easily see all the ContentItems that make up the page in one view, so they can be easily moved by changing the page_order?

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

+6
python django django-models django-admin
source share
1 answer

This is a great way to do it. Unfortunately, Django ORM does not handle model inheritance as smoothly as you might want. page.contents will contain a QuerySet of Content objects. If you want to access subtypes, you need to create some way to suppress the content object. The problem is that this requires a request for an object that can quickly get out of hand. This blog post describes a method for getting mixed subtypes in a single request using select_related() behind the scenes.

+3
source share

All Articles