[Django] 07 - Build a Simple Blog by Wagtail

传统方法


一、资源

系列视频:Django Project - Build a Simple Blog,几个热身的知识点如下:

  • namespace

Ref: 实战Django的URL命名空间namespace【多用户时可能会用到】

 

  • model.manager

Ref: Django 框架之 自定义manager

Post.objects.all() --> 但本意是 只关心:published的条目,所以需要自定义(overwrite)。

改为如下: 

[views.py]

def
home(request): # newmanager自定义了filter all_posts = Post.newmanager.all() # all_posts 给模板的参数 return render(request, 'index.html', {'posts': all_posts})

object的默认定义,以及newmanager的自定义替代者的形式。

[models.py]

class NewManager(models.Manager): def get_queryset(self): return super().get_queryset() .filter(status='published') objects = models.Manager() # default manager newmanager = NewManager() # custom manager

 

  • urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls', namespace='blog')),  # ----> 
]

<key:value>

[blog.urls]

urlpatterns = [ path('', views.home, name='homepage'), path('<slug:post>/', views.post_single, name='post_single'), ]

查看数据库(model) 中是否有对应的数据。没有就返回默认的404页面。

[views.py]

def
post_single(request, post): # 如果有,且还是published,就好;否则,自动返回内置的404页面。 post = get_object_or_404(Post, slug=post, status='published') # post 给模板的参数 return render(request, 'single.html', {'post': post})

 

  • reverse

{% for post in posts %}
  <div class="col-12"><h1>
    <a class="text-dark" href="{{post.get_absolute_url}}">{{post.title}}</a>
  </h1></div>
  <div class="col-12"><p>{{post.excerpt}}</p></div>
{% endfor %}

Django reverse() 反转 url。 

def get_absolute_url(self):
    return reverse('blog:post_single', args=[self.slug])

Ref: Django URL重定向的3种方法详解

Ref: Django基础(10): URL重定向的HttpResponseDirect, redirect和reverse的用法详解【为主】

      1. [HttpResponseDirect方法] 
      2. [redirect方法] 
      3. [reverse方法]

详见:彻底搞懂Django的get_absolute_url方法

 

  可见,还是比较麻烦,不少细节都要自己去处理。

 

 

 

 

Wagtail CMS


总体思路

一、跟着的资源

Learn Wagtail

https://wagtail.io/

Wagtail教程

 

  • 新建项目

wagtail start mysite
cd mysite

# 修改version in requirements.txt: Wagtail 2.5.1 and Django 2.2.2
pip install -r requirements.txt
python manage.py migrate python manage.py createsuperuser python manage.py runserver

python manage.py runserver 0.0.0.0:800

Django version plan: https://www.djangoproject.com/download/#supported-versions

 

  • 补充 Home Page

添加最简单的 banner_title。

class HomePage(Page):
    """
        Home Page Model
    """

    #
    # 新增一个 banner_title,添加到默认的 content_panels
    # 在 html 中可以通过 self.banner_title 读取
    #
    templates = "home/home_page.html"banner_title= models.CharField(max_length=100, blank=False, null=True)

    content_panels = Page.content_panels + [
        FieldPanel("banner_title"),
    ]

其他panels依次类推。

 

  • Django的Template

千锋Python教程:23 HelloTemplate,变量,标签,常见语法1

 

 

二、前四节效果

定制了:

    content_panels = Page.content_panels + [
        FieldPanel("banner_title"),
        FieldPanel("banner_subtitle"),
        ImageChooserPanel("banner_image"),
        PageChooserPanel("banner_cta")
    ]

http://127.0.0.1:8000/ 默认自动加载 “项目目录下template”,这里可以调到app中的model的内容。

有点奇怪:urls.py没有,也没看到view.py。继续,拭目以待。

 

 

 

Debugging

一、django-debug-toolbar

Ref: https://django-debug-toolbar.readthedocs.io/en/latest/installation.html

相比 Django,settings.py演变为了如下:

 

  • 补充 settings/dev.py

# 添加如下三个配置 from https://django-debug-toolbar.readthedocs.io/en/latest/installation.html
INSTALLED_APPS = INSTALLED_APPS + [
    'debug_toolbar',
]

MIDDLEWARE = MIDDLEWARE + [
    'debug_toolbar.middleware.DebugToolbarMiddleware',
]

INTERNAL_IPS = [
    '127.0.0.1',
]

 

  • 补充 mysite/urls.py

(1) 注意 from import的两行内容。

(2) 再补充 urlpatterns 的内容。

from django.conf.urls import include, url
from django.urls import include, pat


import debug_toolbar

urlpatterns = urlpatterns + [
    # For anything not caught by a more specific rule above, hand over to
    # Wagtail's page serving mechanism. This should be the last pattern in
    # the list:
    path("", include(wagtail_urls)),

    # Alternatively, if you want Wagtail pages to be served from a subpath
    # of your site, rather than the site root:
    #    path("pages/", include(wagtail_urls)),

    path('__debug__/', include(debug_toolbar.urls)),
]

更多详见:Django 开发:django-debug-toolbar使用详解

 

二、shell_plus

会自动导入各种ORM的类,直接以命令行的形式去debug/test接口。

教学视频:Wagtail CMS: Setting up Django Shell, shell_plus and ipython to explore your Wagtail Application

pip install django-extensions
pip install ipython
python manage.py shell_plus

 

 

  

UI 模板美化

一、添加 Jumbotron

第一步:css, js 都要天添加 from https://getbootstrap.com/docs/4.2/getting-started/introduction/

第二步:html 代码再添加 from https://getbootstrap.com/docs/4.2/components/jumbotron/

 

二、添加 Navbar

 直接插入 superhero风格的 nav 代码 from: https://bootswatch.com/superhero/

base.html中添加: 

{# Global stylesheets #}

<link rel="stylesheet" href="https://bootswatch.com/4/superhero/bootstrap.min.css" crossorigin="anonymous"> <link rel="stylesheet" type="text/css" href="{% static 'css/mysite.css' %}">

以及 html 添加处:

 

 

  

添加一个全新页面

Ref: How to Add a New Wagtail CMS Page From Scratch【添加一个flex page】

Wagtail,model和view关系更紧密一些。

一、添加套路

第一步,创建

(wagtail) jeffrey@unsw-ThinkPad-T490:mysite$ python manage.py startapp flex
(wagtail) jeffrey@unsw
-ThinkPad-T490:mysite$ ls db.sqlite3 Dockerfile flex home manage.py media mysite requirements.txt search
(wagtail) jeffrey@unsw
-ThinkPad-T490:mysite$ ls flex/ admin.py apps.py __init__.py migrations models.py tests.py views.py

Next, 添加"flex" 到INSTALLED_APPS in settings/base.py.

 

第二步,写模型

from django.db import models

from wagtail.admin.edit_handlers import FieldPanel
from wagtail.core.models import Page


class FlexPage(Page):
    """Flexible page class."""

    template = "flex/flex_page.html"

    # @todo add streamfields
    # content = StreamField()

    subtitle = models.CharField(max_length=100, null=True, blank=True)

    content_panels = Page.content_panels + [
        FieldPanel("subtitle"),
    ]

    class Meta:  # noaq
        verbose_name = "Flex Page"
        verbose_name_plural = "Flex Pages"
View Code

 

第三步,写模板

{% extends "base.html" %}
{% load wagtailcore_tags %}

{% block content %}
    <div class="jumbotron">
        <div class="container">
            <div class="row">
                <div class="col-sm-12 text-center">
                    <h1 class="display-4">{{ self.title }}</h1>
                    <div class="lead">{{ self.subtitle }}</div>
                </div>
            </div>
        </div>
    </div>

{% endblock %}
View Code

  

 基本上,套路明白了。

 

 

二、数据库

[Page list]

 

 

[Page detail] 

 

 

End.

posted @ 2020-12-19 15:19  郝壹贰叁  阅读(223)  评论(0编辑  收藏  举报