實戰Django:小型CMS Part1

CMS,即Content Management System,內容管理系統。咱們這裏要開發的小型CMS應用,從結構上和blog應用有些相似,但咱們會在這裏加入一些新的技術,好比說工做流、搜索功能、編輯組件等。html

 

1.建立項目和應用 python


咱們先來建立本實例的項目,在dos命令提示符下轉到Scripts文件夾(如「c:\python32\Scripts」),而後運行以下命令:數據庫

$ django-admin startproject cmsproject

而後在dos命令提示符下繼續輸入以下命令,進入項目文件夾:django

cd cmsproject

注意,之後的絕大部分操做都在這裏進行,咱們把這個文件夾稱做項目的根文件夾。瀏覽器

接下來開始建立應用,在dos命令提示符下輸入命令:服務器

$ python manage.py startapp cms

命令執行完後,項目根文件夾下會出現一個叫cms的文件夾,應用建立完畢。markdown

2.創建模型 網絡


編輯cms/models.py文件,改爲下面這樣:session

cms/models.py:app

from markdown import markdown
import datetime
from django.db import models
from django.db.models import permalink
from django.contrib.auth.models import User

VIEWABLE_STATUS = [3, 4]

class ViewableManager(models.Manager):
    def get_queryset(self):
        default_queryset = super(ViewableManager, self).get_queryset()
        return default_queryset.filter(status__in=VIEWABLE_STATUS)

class Category(models.Model):
    """文章分類"""
    label = models.CharField(blank=True, max_length=50)
    slug = models.SlugField()

    class Meta:
        verbose_name_plural = "categories"

    def __str__(self):
        return self.label


class Story(models.Model):
    """內容管理系統中的一篇文章"""
    
    STATUS_CHOICES = (
        (1, "待編輯"), 
        (2, "待審覈"), 
        (3, "發佈"),
        (4, "存檔"),
    )

    title = models.CharField(max_length=100)
    slug = models.SlugField()
    category = models.ForeignKey(Category)
    markdown_content = models.TextField()
    html_content = models.TextField(editable=False)
    owner = models.ForeignKey(User)
    status = models.IntegerField(choices=STATUS_CHOICES, default=1)
    created = models.DateTimeField(default=datetime.datetime.now)
    modified = models.DateTimeField(default=datetime.datetime.now)

    class Meta:
        ordering = ['modified']
        verbose_name_plural = "stories"

    def __str__(self):
        return self.title
        
    @permalink
    def get_absolute_url(self):
        return ("cms-story", (), {'slug': self.slug})

    def save(self):
        self.html_content = markdown(self.markdown_content)
        self.modified = datetime.datetime.now()
        super(Story, self).save()

    admin_objects = models.Manager()
    objects = ViewableManager()

注意一下,文件要儲存爲UTF-8編碼.

咱們能夠看到,在Story模型中,引用了兩個其餘的模型(User和Category)。模型的第一塊代碼定義了一個包含四個階段的工做流,固然,你能夠給本身的流程添加更多的步驟。

顧名思義,待編輯和待審覈的文章,是咱們不想讓訪問者看到的。發佈和存檔的區別在於,後者是過了必定時間,將其改成存檔狀態,能夠限制它出如今某些特定的地方,好比說首頁,但內容仍是可讓訪問者在其它地方看到。

定義完STATUS_CHOICES以後就輪到變量的定義。

  • title:咱們要在瀏覽器的標題欄和渲染頁面上顯示的標題。
  • slug:頁面在URL裏惟一的名字。
  • category:文章分類,這是一個指向Category模型的外鍵。
  • markdown_content:Markdown格式的頁面正文(下面會專門介紹Markdown)。
  • html_content:Html格式的頁面文本。咱們會在編輯的時候自動渲染它。爲了不混淆,不能夠直接編輯這個變量,所以,它不會在Django的管理界面應用的編輯表單上顯示出來。
  • owner:擁有這個內容的用戶,不必定是管理員,有多是其它用戶。
  • status:在編輯工做流中的狀態;
  • created:建立的時間,自動設置爲當前時間(利用Python的datetime模塊)。
  • modified:修改的時間,初始化爲當前時間,這個時間戳會顯示在文章的內容頁上。

在Meta嵌套類裏咱們還指定了一個verbose_name_plural的屬性,它的做用是避免模型在應用中顯示「Storys」這樣的錯誤拼寫。

此外還有一個生成永久連接用的get_absolute_url方法,這個咱們已經在上一個「網絡相冊」實例中見過它了。

Category這個模型就很是簡單,只有兩個變量,一個名稱,一個別名。值得注意的是,這是很是方便的一種建立適合的關係型模型的途徑。

咱們的數據庫裏同時包含了已發佈的(狀態3和4)和還沒有發佈的(狀態1和2)文章。咱們還須要一種便捷的方式只把前者顯示到站點的公共頁面上,而在管理界面則顯示所有。

雖然咱們能夠在模板裏用{% if %}標籤來阻止公共頁面顯示還沒有發佈的文章,但這個方案最終會變得異常煩瑣和不斷重複。由於這裏涉及的是業務邏輯而不是表現風格,因此應該在模型中實現這種控制。在Django開發時要把握這樣一項原則,永遠不要把業務邏輯放到模板中,不然時間長了一定一團亂。模板只要作好顯示風格上的事情就能夠了,顯示哪些數據的問題,仍是交給模型和視圖來操心吧!

咱們把這項控制功能經過自定義Manager加到模型裏去,因此咱們在import語句的下方加入了一行「VIEWABLE_STATUS = [3, 4] 」,而後是ViewableManager類,ViewableManager控制住文章數據,確保只輸出狀態等於3或4的文章。

接着,咱們在Story模型裏用admin_objects = models.Manager()定義了一個manager對象,因爲它是先定義的,因此它就是咱們模型的默認manager,這樣就能保證咱們在管理界面編輯全部狀態的文章。
而後咱們用objects = ViewableManager()建立一個自定義的manager實例。咱們將在URL配置和視圖使用這個名字,所以全部的公共頁面都會收到由自定義ViewableManager輸出的通過過濾的queryset。

做爲模型的最後一個部分,咱們重寫了函數save來應用一個輕型的票房語言,叫作Markdown.用戶在管理界面用它來輸入文本,Markdown提供了一種建立Web內容更簡單的方式。
你還能夠選用其它標記語言。這裏咱們主要展現的是如何經過重寫模型的save方法來「神奇自動」地把Markdown轉換成Html,這樣就不須要爲每一個頁面請求執行一次轉換操做了。
固然,咱們還會有更好的選擇,好比說用一個所見即所得的編輯器來代替Markdown,這個你們能夠自行研究。
要使用Markdown,你得先去下載Markdown模塊,下載地址是:https://pypi.python.org/pypi/Markdown/2.5.1,下載完畢,先解壓,而後用python setup.py install命令安裝便可。不會安裝Python模塊的童鞋,請自行百度學習相應的方法。
如何來用好Markdown,能夠看這個頁面裏的資料:http://daringfireball.net/projects/markdown/syntax

3.激活模型


首先修改cmsproject/settings.py這個文件,找到INSTALLED_APPS這段設置,把它改爲下面這個樣子:

cmsproject/settings.py:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'cms',
)

編輯settings.py的時候,建議順便修改一下語言和時區的設置,具體的方法請參考:《實戰Django:官方實例Part1》

而後在dos命令提示符下運行以下命令:

$ python manage.py makemigrations cms

繼續在dos命令提示符下運行命令:

$ python manage.py migrate

這樣,數據庫就建好了。

4.建立管理員帳號


在dos命令提示符下運行以下命令:

$ python manage.py createsuperuser

而後依次輸入admin,你的郵箱,輸入兩次密碼,完成建立管理員的操做。

5.在管理界面註冊應用


編輯cms/admin.py 文件,讓它變成下面這個樣子:

cms/admin.py

from django.contrib import admin
from cms.models import Category, Story

class StoryAdmin(admin.ModelAdmin):
    list_display = ('title', 'owner', 'status', 'created', 'modified')
    search_fields = ('title', 'content')
    list_filter = ('status', 'owner', 'created', 'modified')
    prepopulated_fields = {'slug': ('title',)}

class CategoryAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('label',)}
    
admin.site.register(Category, CategoryAdmin)
admin.site.register(Story, StoryAdmin)

6.啓動服務器


在dos命令提示符下運行以下命令:

$ python manage.py runserver

還記得如何判斷服務器是否成功運行嗎?這裏就很少講了。

咱們先訪問一下管理界面,打開瀏覽器,在地址欄內輸入:

http://127.0.0.1:8000/admin/

而後輸入你剛纔建立的管理員帳號和密碼,登陸管理界面,你會看到下面這樣的畫面:

7

【未完待續】

本文版權歸捨得學苑全部,歡迎轉載,轉載請註明做者和出處。謝謝!
做者:捨得
首發:捨得學苑@博客園

相關文章
相關標籤/搜索