用python搭建一個校園維基網(wǎng)站(二)—— 可編輯內(nèi)容的首頁的創(chuàng)建

項目總體簡介請看用python搭建一個校園維基網(wǎng)站(一)纯路。
本文可獨立使用姥份,創(chuàng)建了一個可編輯內(nèi)容的首頁凡伊,展示了wagtail的一些基礎(chǔ)用法可帽。文末為本文所創(chuàng)項目文件github地址钾军。
比較詳細鳄袍,新手可嘗試,不過最好有一定Django基礎(chǔ)吏恭。

項目結(jié)構(gòu)概觀

  • 首先使用wagtail start geniuspip 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
  1. manage.pyDjango項目通用的管理腳本(通過python manage.py 某命令參數(shù)使用)哀九。
  2. requirements.txt用于存儲當(dāng)前項目的依賴列表(自動生成的為Djangowagtail,虛擬環(huán)境(virtualenv)下可用pip freeze >> requirements.txt追加)搅幅。
  3. 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)界牡。
  4. home是自動生成的app文件夾簿寂,包含了models.py頁面數(shù)據(jù)模型和templates模板文件夾。默認生成的models.py中定義了一個簡單的HomePage類(繼承自wagtailPage類)來代表一個頁面(即默認的歡迎頁)的模型(該簡單模型的可編輯內(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
歡迎頁

歡迎頁模板 - templates/home/home_page.html
  1. search則是自動生成的提供搜索功能的app文件夾漠另,由于基于wagtail.wagtailsearch所以只包含了views.py視圖文件和templates模板文件夾。暫時不管跃赚。

創(chuàng)建wiki主頁

  • 我們先清空數(shù)據(jù)庫笆搓,python manage.py flush或者直接刪除db.sqlite3數(shù)據(jù)庫文件。
  • 在項目根目錄下刪除home文件夾纬傲,新建一個名為wiki的文件夾代表wikiapp满败,并將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)容侠讯。
    此外挖藏,對于TopLinkLittleIntros我們需要另外新建兩個繼承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框架涧衙。
    它有一系列現(xiàn)成的layouts供我們使用哪工,選擇最適合本次主頁的樣式,查看源碼可以得到詳細的信息弧哎,在這里正勒,為了簡便,我們直接使用了該layout的額外樣式表的鏈接(最好處理為本地的css樣式文件傻铣,使用Django的static標簽引用)。
    對于模板來說祥绞,它對應(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)捧毛,在wikiapp目錄下新建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)管理員冶伞。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末新症,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子响禽,更是在濱河造成了極大的恐慌徒爹,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芋类,死亡現(xiàn)場離奇詭異隆嗅,居然都是意外死亡,警方通過查閱死者的電腦和手機侯繁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門胖喳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贮竟,你說我怎么就攤上這事丽焊。” “怎么了咕别?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵技健,是天一觀的道長。 經(jīng)常有香客問我惰拱,道長雌贱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任偿短,我火速辦了婚禮帽芽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘翔冀。我一直安慰自己,他們只是感情好披泪,可當(dāng)我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布纤子。 她就那樣靜靜地躺著,像睡著了一般款票。 火紅的嫁衣襯著肌膚如雪控硼。 梳的紋絲不亂的頭發(fā)上岳枷,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天久妆,我揣著相機與錄音,去河邊找鬼信卡。 笑死缚够,一個胖子當(dāng)著我的面吹牛幔妨,可吹牛的內(nèi)容都是我干的鹦赎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼误堡,長吁一口氣:“原來是場噩夢啊……” “哼古话!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锁施,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤陪踩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后悉抵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肩狂,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年姥饰,在試婚紗的時候發(fā)現(xiàn)自己被綠了傻谁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡媳否,死狀恐怖栅螟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情篱竭,我是刑警寧澤力图,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站掺逼,受9級特大地震影響吃媒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吕喘,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一赘那、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧氯质,春花似錦募舟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至辕漂,卻和暖如春呢灶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钉嘹。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工鸯乃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人跋涣。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓缨睡,卻偏偏與公主長得像鸟悴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宏蛉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容