[Django] 13 - Parent and Child Class of Wagtail

Ref: Wagtail CMS: How to subclass Wagtail Pages

 

使用继承 ORM

一、 继承 - Create new ORM

[ blog/models.py ]

疑问,是否也同时继承了 InlinePanel 的部分?有的! 

# First subclassed blog post page
class ArticleBlogPage(BlogDetailPage):
    """A subclassed blog post page for articles."""

    template = "blog/article_blog_page.html"

    subtitle = models.CharField(
        max_length=100,
        blank=True,
        null=True
    )
    intro_image = models.ForeignKey(
        "wagtailimages.Image",
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        help_text='Best size for this image will be 1400x400'
    )
----------------------------------------------------------------------------- content_panels
= Page.content_panels + [ FieldPanel("custom_title"), FieldPanel("subtitle"), ImageChooserPanel("banner_image"), ImageChooserPanel("intro_image"), MultiFieldPanel( [ InlinePanel("blog_authors", label="Author", min_num=1, max_num=4) ], heading="Author(s)" ), MultiFieldPanel( [ FieldPanel("categories", widget=forms.CheckboxSelectMultiple) ], heading="Categories" ), StreamFieldPanel("content"), ]

 

class VideoBlogPage(BlogDetailPage)
# Second subclassed page
class VideoBlogPage(BlogDetailPage):
    """A video subclassed page."""

    template = "blog/video_blog_page.html"

    youtube_video_id = models.CharField(max_length=30)

    content_panels = Page.content_panels + [
        FieldPanel("custom_title"),
        ImageChooserPanel("banner_image"),
        MultiFieldPanel(
            [
                InlinePanel("blog_authors", label="Author", min_num=1, max_num=4)
            ],
            heading="Author(s)"
        ),
        MultiFieldPanel(
            [
                FieldPanel("categories", widget=forms.CheckboxSelectMultiple)
            ],
            heading="Categories"
        ),
        FieldPanel("youtube_video_id"),
        StreamFieldPanel("content"),
    ]
View Code

 

二、Template 分析

article 主题效果:

    • 标题
    • 类别
    • 作者
    • 图片
    • 文字

 

[1] <img> 标签的alt 属性指定了替代文本,用于在图像无法显示或者用户禁用图像显示时,代替图像显示在浏览器中的内容。

[2] 标题的 logic,参见 [Django] 08 - StreamField of Wagtail

{% extends "base.html" %}

{% load wagtailimages_tags wagtailcore_tags %}

{% block content %}
# 比例 # {% image self.banner_image fill-1200x300 as banner %}
<img src="{{ banner.url }}" alt="{{ banner.alt }}" style='width: 100%; height: auto;'> <div class="container mt-5 mb-5"> <div class="text-center"> <h1> {% if self.custom_title %} {{ self.custom_title }} {% else %} {{ self.title }} {% endif %} </h1> {% if self.subtitle %} <h3>{{ self.subtitle }}</h3> {% endif %}
{% if self.categories.count %}
<div style="padding: 0 20px 20px"> {% for cat in self.categories.all %} <a href="?category={{ cat.slug }}"> {{ cat.name }} </a>{% if not forloop.last %}, {% endif %}  # 有可能是多个类别,最后item后不跟"逗号"的小技巧写法 {% endfor %} </div> {% endif %}
<div class="d-flex justify-content-center"> {% for iter in self.blog_authors.all %} {% image iter.author.image fill-50x50 as img %} <div> <img src="{{ img.url }}" class="rounded-circle" alt="{{ iter.author.name }}"> </div> {% if iter.author.website %} <a href="{{ iter.author.website }}"> {{ iter.author.name }} </a> {% else %} {{ iter.author.name }}  # 有链接就写链接,没有就直接上文本 {% endif %} </div> {% endfor %} </div> </div> </div> {% if self.intro_image %} <div class="container"> <div class="row"> <div class="col-lg-8 offset-lg-2"> {% image self.intro_image fill-1400x400 as intro_img %} <img src="{{ intro_img.url }}" alt="{{ intro_img.alt }}"> </div> </div> </div> {% endif %} <div class="container"> <div class="row"> <div class="col-lg-8 offset-lg-2"> {% for block in self.content %} {% include_block block %} {% endfor %} </div> </div> </div>
{% endblock %}

 

 

 

继承特性

一、自动加载 wagtail package

(wagtail) jeffrey@unsw-ThinkPad-T490:mysite$ python manage.py shell_plus --ipython
# Shell Plus Model Imports
from blog.models import ArticleBlogPage, BlogAuthor, BlogAuthorsOrderable, BlogCategory, BlogDetailPage, BlogListingPage, VideoBlogPage
from django.contrib.admin.models import LogEntry
from django.contrib.auth.models import Group, Permission, User
from django.contrib.contenttypes.models import ContentType
from django.contrib.sessions.models import Session
from flex.models import FlexPage
from home.models import HomePage, HomePageCarouselImages
from mobilar.models import MobilarListingPage, MobilarPage
from site_settings.models import SocialMediaSettings
from subscribers.models import Subscribers
from taggit.models import Tag, TaggedItem
from wagtail.contrib.forms.models import FormSubmission
from wagtail.contrib.redirects.models import Redirect
from wagtail.core.models import Collection, CollectionViewRestriction, GroupCollectionPermission, GroupPagePermission, Page, PageRevision, PageViewRestriction, Site
from wagtail.documents.models import Document
from wagtail.embeds.models import Embed
from wagtail.images.models import Image, Rendition
from wagtail.search.models import Query, QueryDailyHits
from wagtail.users.models import UserProfile
# Shell Plus Django Imports
from django.core.cache import cache
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import transaction
from django.db.models import Avg, Case, Count, F, Max, Min, Prefetch, Q, Sum, When
from django.utils import timezone
from django.urls import reverse
from django.db.models import Exists, OuterRef, Subquery
Python 3.7.5 (default, Nov  7 2019, 10:50:52) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.19.0 -- An enhanced Interactive Python. Type '?' for help.
View Code

 

  • 识别 父类 or 子类

In [1]: posts = BlogDetailPage.objects.all()

In [2]: posts
Out[2]: <PageQuerySet [<BlogDetailPage: Blog Title for  Blog detail page>, <BlogDetailPage: Blog Title for  Blog detail page 2>, <BlogDetailPage: Blog Title for  Blog detail page 3>, <BlogDetailPage: new article>]>

# 显示父类 In [
3]: posts = BlogDetailPage.objects.live().exact_type(BlogDetailPage) In [4]: posts Out[4]: <PageQuerySet [<BlogDetailPage: Blog Title for Blog detail page>, <BlogDetailPage: Blog Title for Blog detail page 2>, <BlogDetailPage: Blog Title for Blog detail page 3>]>
# 显示子类 In [
5]: posts = BlogDetailPage.objects.live().not_exact_type(BlogDetailPage) In [6]: posts Out[6]: <PageQuerySet [<BlogDetailPage: new article>]>

  

  但,类的名字似乎没有对应的变化,不是很友好。

 

  • 显示 子类的 具体信息

体现了 .specific 的作用。

In [2]: articles = BlogDetailPage.objects.live().exact_type(ArticleBlogPage)

In [3]: articles
Out[3]: <PageQuerySet [<BlogDetailPage: new article>]>

In [
4]: articles = BlogDetailPage.objects.live().exact_type(ArticleBlogPage).specific(defer=False) In [5]: articles Out[5]: <PageQuerySet [<ArticleBlogPage: new article>]>

 

End.

posted @ 2020-12-29 13:55  郝壹贰叁  阅读(140)  评论(0编辑  收藏  举报