Wagtailチュートリアル 16 親ページと子ページ

#Wagtailチュートリアル 16
<= [15 adminページにSUBSCRIBERを追加](https://qiita.com/tagawahirotaka/items/e21fedd20450b30173fd)

##親ページと子ページ

```python3 manage.py startapp blog```
base.pyに追加

35

```python:blog/models.py

"""Blog listing and blog detail pages."""
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel
from django.db import models

from wagtail.core.models import Page
from wagtail.core.fields import StreamField
from wagtail.images.edit_handlers import ImageChooserPanel

from streams import blocks

# 35 追加
class BlogListingPage(Page):
    """Listing page lists all the Blog Detail Pages."""

    template = "blog/blog_listing_page.html"

    custom_title = models.CharField(
        max_length=100,
        blank=False,
        null=False,
        help_text="Overwrites the default title",
    )

    content_panels = Page.content_panels + [FieldPanel("custom_title")]

    def get_context(self, request, *args, **kwargs):
        """Adding custom stuff to our context."""
        context = super().get_context(request, *args, **kwargs)
        context["posts"] = BlogDetailPage.objects.live().public()
        return context


# 35 追加
class BlogDetailPage(Page):
    """Blog detail page."""

    custom_title = models.CharField(
        max_length=100,
        blank=False,
        null=False,
        help_text="Overwrites the default title",
    )
    blog_image = models.ForeignKey(
        "wagtailimages.Image",
        blank=False,
        null=True,
        related_name="+",
        on_delete=models.SET_NULL,
    )

    content = StreamField(
        [
            ("title_and_text", blocks.TitleAndTextBlock()),
            ("full_richtext", blocks.RichtextBlock()),
            ("simple_richtext", blocks.SimpleRichtextBlock()),
            ("cards", blocks.CardBlock()),
            ("cta", blocks.CTABlock()),
        ],
        null=True,
        blank=True,
    )

    content_panels = Page.content_panels + [
        FieldPanel("custom_title"),
        ImageChooserPanel("blog_image"),
        StreamFieldPanel("content"),
    ]
```

36

```html:wagtailtutrial/templates/blog/blog_listing_page.html

{% extends "base.html" %}
	
	{% load wagtailimages_tags %}
	
	{% block content %}
	
	    <div class="container">
	        {% for post in posts %}
	            <div class="row mt-5 mb-5">
	                <div class="col-sm-3">
	                    {% image post.blog_image fill-250x250 as blog_img %}
	                    <a href="{{ post.url }}">
	                        <img src="{{ blog_img.url }}" alt="{{ blog_img.alt }}">
	                    </a>
	                </div>
	                <div class="col-sm-9">
	                    <a href="{{ post.url }}">
	                        <h2>{{ post.custom_title }}</h2>
	                        {# @todo add a summary field to BlogDetailPage; make it a RichTextField with only Bold and Italic enabled. #}
	                        <a href="{{ post.url }}" class="btn btn-primary mt-4">Watch More</a>
	                    </a>
	                </div>
	            </div>
	        {% endfor %}
	    </div>
	{% endblock content %} 
```

37

```html:wagtailtutrial/templates/blog/blog_detail_page.html

{#37 追加#}
{% extends "base.html" %}
	
	{% load wagtailimages_tags wagtailcore_tags %}
	
	{% block content %}
	    {% image self.blog_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>{{ self.custom_title }}</h1>
	        </div>
	    </div>
	
	    <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 %} 
```

38

```html:wagtailtutrial/templates/base.html

{% load static wagtailuserbar %}

<!DOCTYPE html>
<html class="no-js" lang="en">
    <head>
        <meta charset="utf-8" />
        <title>
            {% block title %}
                {% if self.seo_title %}{{ self.seo_title }}{% else %}{{ self.title }}{% endif %}
            {% endblock %}
            {% block title_suffix %}
                {% with self.get_site.site_name as site_name %}
                    {% if site_name %}- {{ site_name }}{% endif %}
                {% endwith %}
            {% endblock %}
        </title>
        <meta name="description" content="" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />

        {# 15 bootstrapのsuperheroを追加 #}
        {# 32 fontawsome #}
        <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
        <link rel="stylesheet" href="https://bootswatch.com/4/superhero/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" type="text/css" href="{% static 'css/wagtailtutorial.css' %}">

        {% block extra_css %}
            {# Override this in templates to add extra stylesheets #}
        {% endblock %}
    </head>

    <body class="{% block body_class %}{% endblock %}">
        {% wagtailuserbar %}

{# 15 superheroの上バーをコピペ#}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">PokeApi</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarColor03" aria-controls="navbarColor03" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  {#38  コメントを外す#}
  <div class="collapse navbar-collapse" id="navbarColor03">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/blog/">Blog</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/about/">About</a>
      </li>
    </ul>
  </div>
</nav>

        {#②home_page.htmlへ#}
        {% block content %}{% endblock %}

        {# 12 bootstrapを追加#}
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>


        {# Global javascript #}
        <script type="text/javascript" src="{% static 'js/wagtailtutorial.js' %}"></script>

        {% block extra_js %}
            {# Override this in templates to add extra javascript #}
        {% endblock %}
    </body>
</html>
```

35

<img width="1440" alt="スクリーンショット 2019-08-30 14.37.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/964f1e70-c430-71de-032c-e51a44cf060d.png">

<img width="1440" alt="スクリーンショット 2019-08-30 14.41.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/3b56c2ca-319f-6079-8683-4047d2190f9e.png">

<img width="1440" alt="スクリーンショット 2019-08-30 14.43.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/1a21ec32-eeae-a4b9-39bc-119146b9e672.png">

36
<img width="1440" alt="スクリーンショット 2019-08-30 15.22.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/6cdc8140-52a8-7d84-d2d9-49099313e3c5.png">

37
<img width="1440" alt="スクリーンショット 2019-08-30 15.22.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/ca3e7540-989c-a735-0642-cd66fff18504.png">

38
<img width="1440" alt="スクリーンショット 2019-08-30 15.30.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/60d0b0b9-7f89-3d8b-2c82-bb3064c5cb62.png">