实战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

【未完待续】

本文版权归舍得学苑全部,欢迎转载,转载请注明做者和出处。谢谢!
做者:舍得
首发:舍得学苑@博客园

相关文章
相关标签/搜索