实战Django:小型CMS Part1

CMS,即Content Management System,内容管理系统。我们这里要开发的小型CMS应用,从结构上和blog应用有些类似,但我们会在这里加入一些新的技术,比如说工作流、搜索功能、编辑组件等。

1.创建项目和应用



我们先来创建本实例的项目,在dos命令提示符下转到Scripts文件夹(如“c:\python32\Scripts”),然后运行如下命令:

$ django-admin startproject cmsproject

然后在dos命令提示符下继续输入如下命令,进入项目文件夹:

cd cmsproject

注意,以后的绝大部分操作都在这里进行,我们把这个文件夹称作项目的根文件夹。

接下来开始创建应用,在dos命令提示符下输入命令:

$ python manage.py startapp cms

命令执行完后,项目根文件夹下会出现一个叫cms的文件夹,应用创建完毕。

2.建立模型



编辑cms/models.py文件,改成下面这样:

cms/models.py:

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/

然后输入你刚才创建的管理员账号和密码,登录管理界面,你会看到下面这样的画面:

【未完待续】

本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!

作者:舍得

首发:舍得学苑@博客园

时间: 2024-10-06 08:05:31

实战Django:小型CMS Part1的相关文章

实战Django:官方实例Part1

[写在前面] 撰写这个实战系列的Django文章,是很久之前就有的想法,问题是手头实例太少,一旦开讲,恐有"无米下锅"之忧. 随着对Django学习的深入,渐渐有了些心得,把这些心得整理出来,以规范的.方便新人上手的撰写方式来写这个实战系列,相信对刚接触Django的童鞋会有一定的帮助. 舍得这里所用到的版本,为Django 1.7.1,Python 3.2,想要按照舍得讲解的实例上手练习的话,请务必与舍得所用的版本保持一致. 实例是在Windows系统下调试的,如果你采用的是非Win

实战Django:Rango Part1

在前面我们已经陆续学习了六个Django的实例,其中一个来自Django官方的文档,另外五个来自<Django Web开发指南>.舍得介绍的每一个实例,都是按照官方文档的标准,力求让大家在根据文章去做自己的实例时,能够按"文"索骥,轻松再现整个实例的制作过程. 接下来,舍得要介绍一个大型的实例,这个项目叫做Rango,它来自Django圈内口碑甚佳的<How to Tango with Django>一书.事实上,此书就是围绕Rango这一个实例来展开的,而且,

实战Django:网络相册Part1

这个实例与上个实例一样,源自<Django Web开发指南>,舍得根据Django 1.7.1的特性进行了重新编写. <Django Web开发指南>中所用的Django是1.0版,和现在的最新版本相比,有很大差异,比如通用视图.URL.静态文件的处理等等.最初做这本书的实例时,这些变化曾给舍得带来很大的困扰,还好,实例做得多了,慢慢掌握了一些规律,最终把这些实例修改成在Django 1.7.1下可以运行的版本.   1.创建项目和应用 我们先来创建本实例的项目,在dos命令提示符

实战Django:小型CMS Part2

回顾一下我们之前讲过的几个实例的流程,现在,我们只要添加一些内容(用来测试),创建视图.模板和URL模式,就能完成这个小型的CMS了.   7.添加内容 我们先来创建一个分类,点击Categories后面的"增加"按钮,然后在Label文本框中输入:"Django",在slug文本框后面输入"django"(django不用输入也能自动出现,你可以改成自己喜欢的名字): 随后点击后面的"保存"按钮. 点击左上方的"首

实战Django:简易博客Part1

舍得学习新技能的时候,通常不喜欢傻读书--捧着一本阐述该项技能的书籍,然后傻看,一路看下来,脑子里塞满了新的概念.知识点,头是越来越大,但技能却几乎没掌握半分. 多年来,舍得养成了用做实例来学习新技能的习惯.这可不是舍得的独创,在象棋.围棋界中,历来有"打谱"一说,就是根据棋谱,把一步步棋摆出来,在打谱的过程中,去感悟.去吸收,此时感悟到的.吸收进的,才是属于你自己的东西.新的技能就这样一步步发展起来,逐渐壮大. 就象Django官方文档那样,一个实例看起来很简单,但作为初学者,用&q

实战Django:简易博客Part2

在Part1中,我们完成了本项目的基本框架搭建,并完善了一下管理后台,现在我们来看如何设计面向公共的页面部分. 8.创建模板 首先,请在blog文件夹下建立templates文件夹,然后,在templates文件夹中建立一个叫bog的文件夹,在这个bog文件夹下新建一个archive.html文件,这个文件的路径应该是: bog/templates/bog/archive.html 把下面这些代码添加到archive.html中: bog/templates/bog/archive.html:

实战Django:Pastebin

  这是<Django Web开发指南>中的最后一个实例.如果说上一个实例Liveblog重点讲的是Django和Ajax的协作,那么我们在Pastebin中,将学习到Django和高亮语法JS的协作,顺便复习一下在Django中加入表单. 1.创建项目和应用 我们先来创建本实例的项目,在dos命令提示符下转到Scripts文件夹(如"c:\python32\Scripts"),然后运行如下命令: $ django-admin startproject pastebinpr

实战Django:LiveBlog

<Django Web开发指南>的实例讲的差不多了,除了今天要介绍的LiveBlog,还有一个Pastebin.这样,书中的实例基本讲完了.做完这些实例之后,舍得建议回头看看这本书,或许你会从书中找到舍得所讲的实例里忽略掉的一些细节.此外,<Django Web开发指南>中有几个章节是关于Django的基础或高级技术的,建议阅读并设法把它应用到你所练习过的实例中. 正如你已经看到的,Django提供了丰富的内置功能,你可以很轻松地用这些功能来完成很多工作.但和所有的工具一样,Dja

.NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了

作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/9985451.html 本来这篇只是想简单介绍下ASP.NET Core MVC项目的(毕竟要照顾到很多新手朋友),但是转念一想不如来点猛的(考虑到急性子的朋友),让你通过本文的学习就能快速的入门ASP.NET Core.既然是快速入门所以过多过深的内容我这里就一笔带过了!然后在后面的一些列文章中再慢慢的对其中的概念进行阐述. 本文已收录至.NET Core实战项目之CMS 第一章 入门篇-开篇及总体规