本文转载自http://www.dannysite.com/blog/234/
美好的构想
一个好的产品要从一个好的构思开始,也就是说我们要真正明白想实现什么、要达到怎样的效果。当然,这里的例子并不能称得上是一个“美好的构想”。仅仅包含以下基本的构思:
- 博客拥有标题、作者、正文及发布的时间等基本的元素。同时,一个博客还会隶属于一个分类,并可能包含一个或多个标签。博客也可以有一个或多个评论,评论中要记录评论者的称呼、邮箱以及评论内容;
- 需要有一个“博客列表”页来呈现发布的博客。博客要按发布时间的倒叙来排列,每个博客都要包含标题、作者、分类、发布时间的显示(年-月-日 时:分)及节选的正文内容(前 100 个字)。点击单独的博客可以进入其详情页;
- 需要有一个“详情”页来呈现完整的博客,包括标题、作者、分类、发布的时间、标签和完整的正文内容,并附加评论显示和发布功能。
为了最简化,我不打算用上样式布局。有时候从简开始也许会让思路更为清晰。也正因为这只是一个示例,所以这一节会有一种空荡荡的感觉。而在真正的产品开发中,诸如产品需求分析、原型设计等环节都是相当重要而繁杂的工作。
新增一个 APP
博客算是一个功能集,因此我们应将其体现为一个模块。这表现在 Django 应用里则是为其创建一个 APP Package。现在让 manage.py 中的 startapp 闪亮登场:
python manage.py startapp blog
这样,工程根目录下会增加一个 blog package 并包含如下文件/目录:
其中:
- migrations 下包含对模型定义与修改的迁移记录;
- admin.py 是对 Django 站点管理的定制;
- apps.py 包含对 App 的配置;
- models.py 应包含定义的模型;
- tests.py 包含单元测试;
- views.py 应包含各种视图。
注意释义中的“应”这个字,这是代表不一定要完全这么做,他们只是 Django 建议的结构。事实上“怎么玩”完全可以取决于自己,进而打造一种属于自己的代码结构。然后还需要做一件事,就是注册这个新的 APP,这样在运行工程的时候 Django 才会去识别它。打开 myblog/settings.py,在 INSTALLED_APPS 添加 blog:
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
铸造基石 —— 模型的建立
从分析“要实现什么”中,我们应该对这个要实现的系统有一个整体的认识与把控。接下来首先要做的就是通过需求来建立模型,即 M 层,它决定了数据的存取。之前的需求中存在这样的一句话:
博客拥有标题、作者、正文及发布的时间等基本的元素。同时,一个博客还会隶属于一个分类,并可能包含一个或多个标签。博客也可以有一个或多个评论,评论中要记录评论者的称呼、邮箱以及评论内容;
从中可以看出:
- 直接与博客相关的模型应包含三个:博客、分类以及标签。博客包含标题、作者、正文、发布时间等基础字段。分类和标签则应有名称;
- 一个博客仅隶属于一个分类,反过来一个分类则可以包含多个博客,这是明显的一对多的关系,因此博客中应有一个外键关联至分类;
- 一个博客可能包含一个或多个标签,反过来一个标签页会包含多个博客,因此是多对多的关系;
- 还有一个评论模型来存储用户评论,并主动关联到博客上去。一个博客可以有一个或多个评论,但反过来评论只针对一篇博客,因此也是一对多的关系。
接下来我们可以以此建立对应的模型,最基础的代码如下:
from django.db import models
class Category(models.Model):
"""
分类
"""
name = models.CharField('名称', max_length=16)
class Tag(models.Model):
"""
标签
"""
name = models.CharField('名称', max_length=16)
class Blog(models.Model):
"""
博客
"""
title = models.CharField('标题', max_length=32)
author = models.CharField('作者', max_length=16)
content = models.TextField('正文')
created = models.DateTimeField('发布时间', auto_now_add=True)
category = models.ForeignKey(Category, verbose_name='分类')
tags = models.ManyToManyField(Tag, verbose_name='标签')
class Comment(models.Model):
"""
评论
"""
blog = models.ForeignKey(Blog, verbose_name='博客')
name = models.CharField('称呼', max_length=16)
email = models.EmailField('邮箱')
content = models.CharField('内容', max_length=140)
created = models.DateTimeField('发布时间', auto_now_add=True)
模型只是利用 Django 提供的 ORM 完成对实际表结构的映射,因此在完成模型定义后,我们需要将其真正同步到实际的数据库中去。新版本的 Django 中,该操作需要分成两步,第一步是生成 migrations:
$ python manage.py makemigrations blog
会生成如下所示的文件:
然后执行 migrate 命令来进行数据库的同步操作:
$ python35 manage.py migrate
Operations to perform:
Apply all migrations: admin, contenttypes, auth, blog, sessions
Running migrations:
Rendering model states... DONE
Applying blog.0001_initial... OK
注意最后一行,说明新的表已经成功同步至数据库。
添加内容
既然存储博客的地方已经有了,现在是时候尝试往里面插入一些数据了,这也方便之后在实现功能之后进行测试。传统的方式可以选择手动连接到数据库,写原生的 SQL 来完成该步骤。当然还有一个更“酷”的方法就是利用 Django 内置的站点管理工具。(在前一章中我在最后的“发现更多”中提到了站点管理并建议你做一些简单的尝试,如果忽略了这一步的话,在做接下来的操作之前,你可能需要先运行 manage.py createsuperuser 命令创建一个超级管理员账户)。
我们已经注意到在 app 目录下的 admin.py 文件,要想让定义的模型在站点管理中展示,就需要在此将所需的模型显示的添加进去。打开 blog/admin.py 文件并添加如下内容:
from django.contrib import admin
from .models import Category, Tag, Blog
admin.site.register([Category, Tag, Blog])
重新运行 runserver 开发服务器并通过 /admin/ 访问后台,应该能看到我们所期望的内容:
怎么样?是不是很神奇!赶紧添加一条数据试试吧!