項目總體簡介請看用python搭建一個校園維基網(wǎng)站(一)纯路。
本文可獨立使用姥份,創(chuàng)建了一個可編輯內(nèi)容的首頁凡伊,展示了wagtail的一些基礎(chǔ)用法可帽。文末為本文所創(chuàng)項目文件github地址钾军。
比較詳細鳄袍,新手可嘗試,不過最好有一定Django基礎(chǔ)吏恭。
項目結(jié)構(gòu)概觀
- 首先使用
wagtail start genius
(pip install wagtail
安裝依賴)創(chuàng)建名為genius
的工程文件夾拗小,cd genius
進入目錄。 - 在windows命令行輸入
tree /a /f > 1.txt
在當(dāng)前目錄下生成1.txt
看到如下的項目結(jié)構(gòu)樱哼。
E:.
| manage.py
| requirements.txt
|
+---genius
| | urls.py
| | wsgi.py
| | __init__.py
| |
| +---settings
| | base.py
| | dev.py
| | production.py
| | __init__.py
| |
| +---static
| | +---css
| | | genius.css
| | |
| | \---js
| | genius.js
| |
| \---templates
| 404.html
| 500.html
| base.html
|
+---home
| | models.py
| | __init__.py
| |
| +---migrations
| | 0001_initial.py
| | 0002_create_homepage.py
| | __init__.py
| |
| \---templates
| \---home
| home_page.html
|
\---search
| views.py
| __init__.py
|
\---templates
\---search
search.html
-
manage.py
是Django
項目通用的管理腳本(通過python manage.py 某命令參數(shù)
使用)哀九。 -
requirements.txt
用于存儲當(dāng)前項目的依賴列表(自動生成的為Django
和wagtail
,虛擬環(huán)境(virtualenv)下可用pip freeze >> requirements.txt
追加)搅幅。 -
genius
包含項目主要信息阅束,有主路由(urls.py
)、wsgi接口(wsgi.py
)茄唐、配置文件夾(分基礎(chǔ)配置base.py
息裸、開發(fā)環(huán)境配置dev.py
與生產(chǎn)環(huán)境配置production.py
,后二者依賴基礎(chǔ)配置)、全局靜態(tài)資源文件夾(static
)與模板資源文件夾(templates
)界牡。 -
home
是自動生成的app文件夾簿寂,包含了models.py
頁面數(shù)據(jù)模型和templates
模板文件夾。默認生成的models.py
中定義了一個簡單的HomePage
類(繼承自wagtail
的Page
類)來代表一個頁面(即默認的歡迎頁)的模型(該簡單模型的可編輯內(nèi)容部分只有title
字段)宿亡。在wagtail
的概念中常遂,頁面模型和模板文件是默認關(guān)聯(lián)的,如HomePage
默認對應(yīng)的模板為templates/home/home_page.html
(注意命名的轉(zhuǎn)換關(guān)系)挽荠,而歡迎頁http://127.0.0.1:8000
中的大部分內(nèi)容就在該模板中(該模板使用extends
語句繼承genius\templates\base.html
克胳,并使用block
語句填充相應(yīng)內(nèi)容)。如下:
# 在命令行中先遷移數(shù)據(jù)庫再啟動服務(wù)圈匆,即可在本地查看歡迎頁面
python manage.py migrate
python manage.py runserver
-
search
則是自動生成的提供搜索功能的app文件夾漠另,由于基于wagtail.wagtailsearch
所以只包含了views.py
視圖文件和templates
模板文件夾。暫時不管跃赚。
創(chuàng)建wiki主頁
- 我們先清空數(shù)據(jù)庫笆搓,
python manage.py flush
或者直接刪除db.sqlite3
數(shù)據(jù)庫文件。 - 在項目根目錄下刪除
home
文件夾纬傲,新建一個名為wiki
的文件夾代表wiki
app满败,并將genius\settings\base.py
配置文件中第28行左右的INSTALLED_APPS
列表中的home
改為wiki
,以此來向配置文件注冊我們的app叹括。并在wiki
文件夾里添加目錄和空文件:
\---wiki
| models.py
| __init__.py
|
+---migrations
| __init__.py
|
\---templates
\---wiki
- 現(xiàn)在創(chuàng)建我們的主頁模型算墨,主要元素如下:
我們的WikiHome
頁面模型中需要圖中紅色高亮的一系列字段,其中title
字段繼承自Page
類汁雷,不用額外添加净嘀,image
字段為連接到wagtailimages.Image
模型的外鍵。content_panels
列表提供了該頁面模型在后臺管理編輯頁面的呈現(xiàn)內(nèi)容侠讯。
此外挖藏,對于TopLink
和LittleIntros
我們需要另外新建兩個繼承wagtail
提供的Orderable
(使有序)的非頁面模型。
WikiHomeLittleIntros
的字段有fontawesome圖標類名继低,小標題和簡述熬苍,如下圖。還包含了一個wagtail
提供的對ForeignKey
進行了一層封裝的ParentalKey
外鍵連接到它所屬的WikiHome
頁面袁翁。類似的柴底,panels
表明出現(xiàn)在可編輯區(qū)。
WikiHomeTopLink
類似粱胜,為了層次上更清晰柄驻,采用了多重繼承,在models.py
中只定義ParentalKey
外鍵焙压,而在另一個文件中定義了RelatedLink
模型鸿脓,包含的字段有鏈接文本和具體鏈接抑钟,只是具體鏈接可能為外鏈、某個頁面或某個文檔野哭,占用了三個字段在塔,此外還利用@property
裝飾器為該模型添加了link
屬性,來返回它的具體鏈接拨黔,這樣在模板中就可以使用.link
調(diào)用蛔溃。
綜上,models.py
的內(nèi)容為:
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.wagtailcore.models import Page, Orderable
from wagtail.wagtailadmin.edit_handlers import (
FieldPanel, InlinePanel)
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from .umodels import RelatedLink
# ------------------------主頁-------------------------
class WikiHome(Page):
logoname = models.CharField(
max_length=255,
help_text=u"顯示在左上角的網(wǎng)頁名稱"
)
image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
help_text=u"大幅背景圖"
)
intro = models.TextField(
blank=True,
help_text=u"下方簡單口號"
)
content_panels = Page.content_panels + [
FieldPanel('logoname'),
InlinePanel('toplinks', label="頂部右側(cè)鏈接"),
ImageChooserPanel('image'),
FieldPanel('intro', classname="full"),
InlinePanel('little_intros', label="下方一排推廣簡述"),
]
class WikiHomeTopLink(Orderable, RelatedLink):
page = ParentalKey('wiki.WikiHome', related_name='toplinks')
class WikiHomeLittleIntros(Orderable):
page = ParentalKey(WikiHome, related_name='little_intros')
fa_name = models.CharField(blank=True, max_length=250,
help_text=u'''FontAwesome圖標類名
- 參考fontawesome.io/icons/''')
title = models.CharField(blank=True, max_length=250,
help_text=u"小標題")
caption = models.CharField(blank=True, max_length=1000,
help_text=u"簡述")
panels = [
FieldPanel('fa_name'),
FieldPanel('title'),
FieldPanel('caption'),
]
在models.py
旁新建umodels.py
文件供models.py
引用:
#--------------------------umodels.py----------------------------#
from django.db import models
from wagtail.wagtailadmin.edit_handlers import (FieldPanel,
PageChooserPanel,
MultiFieldPanel)
from wagtail.wagtaildocs.edit_handlers import DocumentChooserPanel
class LinkFields(models.Model):
link_external = models.URLField("External link", blank=True)
link_page = models.ForeignKey(
'wagtailcore.Page',
null=True,
blank=True,
related_name='+'
)
link_document = models.ForeignKey(
'wagtaildocs.Document',
null=True,
blank=True,
related_name='+'
)
@property
def link(self):
if self.link_page:
return self.link_page.url
elif self.link_document:
return self.link_document.url
else:
return self.link_external
panels = [
FieldPanel('link_external'),
PageChooserPanel('link_page'),
DocumentChooserPanel('link_document'),
]
class Meta:
abstract = True
# Related links
class RelatedLink(LinkFields):
title = models.CharField(max_length=255, help_text="鏈接顯示文本")
panels = [
FieldPanel('title'),
MultiFieldPanel(LinkFields.panels, "Link"),
]
class Meta:
abstract = True
- 這樣篱蝇,我們的wiki首頁模型就定義好了贺待。
- 該創(chuàng)建頁面模型對應(yīng)的模板了,在wiki文件夾下新建
templates\wiki\wiki_home.html
模板文件零截。 - 首先要考慮的是模板的大概樣式該怎么做麸塞,感謝開源世界,我們找到了輕量美觀的purecss框架涧衙。
對于模板來說祥绞,它對應(yīng)的頁面模型處于它的上下文環(huán)境非洲,在模板中可以調(diào)用到該頁面模型中的所有元素(使用Django的模板語言)。我們要按照頁面排版將元素填充進去蜕径。
修改wiki_home.html
中內(nèi)容如下:
{% extends "base.html" %}
{% load wagtailcore_tags wagtailimages_tags %}
{% block extra_css %}
<link rel="stylesheet" >
<link rel="stylesheet" >
<link rel="stylesheet" >
<link rel="stylesheet" >
{% endblock %}
{% block body_class %}wiki-homepage{% endblock %}
{% block content %}
<div class="header">
<div class="home-menu pure-menu pure-menu-horizontal pure-menu-fixed">
<a class="pure-menu-heading" href="">{{ page.logoname }}</a>
<ul class="pure-menu-list">
<li class="pure-menu-item pure-menu-selected"><a href="{{ page.url }}" class="pure-menu-link" style="color:white">首頁</a></li>
{% for item in page.toplinks.all %}
<li class="pure-menu-item"><a href="{{ item.link }}" class="pure-menu-link">{{ item.title }}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% image page.image original as image %}
<div class="splash-container" style="background-image: url({{ image.url }}); background-size:cover">
<div class="splash">
<h1 class="splash-head" style="color: black">{{ page.title }}</h1>
<p class="splash-subhead">
</p>
<p>
<form class="pure-form" action="/search">
<input type="text" name="query" placeholder="請在此輸入搜索內(nèi)容...">
<button type="submit" class="pure-button pure-button-primary">Get Started</button>
</form>
</p>
</div>
</div>
<div class="content-wrapper">
<div class="content">
<h2 class="content-head is-center">{{ page.intro }}</h2>
<div class="pure-g">
{% for item in page.little_intros.all %}
<div class="l-box pure-u-1 pure-u-md-1-2 pure-u-lg-1-4">
<h3 class="content-subhead">
<i class="fa {{ item.fa_name }}"></i>
{{ item.title }}
</h3>
<p> {{ item.caption }} </p>
</div>
{% endfor %}
</div>
</div>
<div class="l-box-lrg pure-g" style="height:20px">
</div>
{% load wiki_tags %}
{% wikihome_footer %}
</div>
{% endblock %}
{% block extra_js %}
{% endblock %}
- 這樣两踏,大致就成功了,但是模板中倒數(shù)幾行里的
{% load wiki_tags %} {% wikihome_footer %}
還沒有實現(xiàn)兜喻,它就是之前圖中黃色框圈住的頁腳了梦染。考慮到頁腳的內(nèi)容一般比較固定朴皆,我們使用snippets和模板標簽tag的形式來實現(xiàn)帕识。它使得我們既可以在管理控制頁面修改該頁腳的內(nèi)容,也使得頁腳具有自己的一小段html模板遂铡,可以簡便地被其它模板所調(diào)用肮疗。 - 在
wiki
文件夾下的models.py
文件旁新建一個snippets.py
文件,添加如下內(nèi)容:
from wagtail.wagtailsnippets.models import register_snippet
from django.db import models
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel
@register_snippet
class FooterText(models.Model):
body = RichTextField()
panels = [
FieldPanel('body'),
]
def __str__(self):
return u"頁面最底部文本 - 限單條"
class Meta:
verbose_name_plural = u'頁面最底部文本'
實際上扒接,它還是創(chuàng)建了一個Django模型伪货,只包含了一個富文本字段们衙,但是利用Wagtail
提供的register_snippet
裝飾器我們可以簡便地將其注冊到管理界面,以便在管理界面修改碱呼。但是蒙挑,還不能在模板中調(diào)用它,我們需要將它注冊到Django的tag標簽系統(tǒng)中愚臀,在wiki
目錄下新建templatetags
文件夾忆蚀,在該文件夾下新建wiki_tags.py
文件,添加如下內(nèi)容懊悯。同樣蜓谋,借助簡單的裝飾器注冊了該模板標簽,且與wiki/tags/footer.html
片段模板綁定炭分,并提供footer_text
作為上下文桃焕。
from django import template
from wiki.snippets import FooterText
register = template.Library()
@register.inclusion_tag('wiki/tags/footer.html', takes_context=True)
def wikihome_footer(context):
footer_text = ""
if FooterText.objects.first() is not None:
footer_text = FooterText.objects.first().body
return {
'footer_text': footer_text,
}
然后就該創(chuàng)建對應(yīng)的片段模板文件了。與上面代碼中綁定的html文件路徑對應(yīng)捧毛,在wiki
app目錄下新建templates\wiki\tags\footer.html
文件观堂,添加如下內(nèi)容:
{% load wagtailcore_tags %}
<div class="footer l-box is-center">
{{ footer_text|richtext }}
</div>
- 好了,主頁的所有代碼部分都結(jié)束了呀忧。讓我們嘗試運行师痕。在項目根目錄下執(zhí)行:
python manage.py makemigrations # 創(chuàng)建數(shù)據(jù)庫遷移文件
python manage.py migrate # 執(zhí)行數(shù)據(jù)庫遷移
python manage.py createsuperuser # 創(chuàng)建超級管理員,郵箱隨意
python manage.py runserver # 啟動服務(wù)
- 登錄管理界面:
http://127.0.0.1:8000/admin/
點擊紅圈部分來到如下圖頁面而账,刪除默認頁面胰坟。
確認刪除后,選擇在根目錄下新建頁面
這時便來到我們的創(chuàng)建的WikiHome模型的頁面元素填寫界面泞辐,依次填寫后按紅圈處Publish提交笔横。
頁面創(chuàng)建好后,我們需要將其掛載到站點上來正常顯示咐吼,點擊下圖紅框創(chuàng)建站點
如下圖創(chuàng)建并保存吹缔,Root Page
選擇新創(chuàng)建的頁面。
最終锯茄,訪問http://127.0.0.1:8000/ 便可以看到頁面效果厢塘。
-
不過細心的朋友可能會發(fā)現(xiàn)頁腳還是空的,我們還需要在管理界面設(shè)置下頁腳肌幽,點擊snippets欄晚碾,并點擊紅圈
創(chuàng)建并保存
- 大功告成,我們的頁腳也完善了牍颈,整個首頁的制作就此完成迄薄。全部代碼與樣例頁面所在數(shù)據(jù)庫在github上,wagtail-tutorial-1煮岁,可直接運行讥蔽,管理員賬號lake涣易,密碼123,也可另創(chuàng)管理員冶伞。