前一部分,我们已经成功创建了博客项目,是时候正是施工了...
这一部分的主要内容:
· 了解Django的开发模式
· 配置数据库
· 创建你的博客APP
· 创建模型
一、Django的MVC模式/MTV模式(摘自《The Django Book》):
Django紧紧地遵循MVC模式,可以称得上是一种MVC框架。 以下是Django中M、V和C各自的含义:
· M:数据存取部分,由django数据库层处理;
· V:选择显示哪些数据要显示以及怎样显示的部分,由视图和模板处理;
· C:根据用户输入委派视图的部分,由Django框架根据URLconf设置,对给定URL调用适当的Python函数。
由于C由框架自行处理,而Django里更关注的是模型(Model)、模板(Template)和视图(Views),Django也被称为MTV框架。在MTV开发模式中:
· M代表模型(Model):即数据存取层。该层处理与数据相关的所有事务:如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等;
· T代表模板(Template):即表现层。该层处理与表现相关的决定:如何在页面或其他类型文档中进行显示。
· V代表视图(View),即业务逻辑层。该层包含存取模型及调取恰当模板的相关逻辑。你可以把它看作模型与模板之间的桥梁。
二、配置数据库和创建新的APP:
之前我们已经知道,Django的MTV开发模式中M代表模型(Model),即处理与数据相关的所有事务,存储数据必然要用到数据库,所以第一步,我们需要对此进行配置。
在之前创建项目时,Django为我们生成了一个setting.py文件,打开它并找到如下行:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': '', # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
Django支持很多种数据库,如MySQL、PostgreSQL、Oracle、SQLite3等。这里为了方便选用SQLite3,它是一款开源、嵌入式关系型数据库。我使用的是Python 2.6,其内置了sqlite3模块,可以很方便地使用。对之前的settings.py做如下修改:
'ENGINE': 'django.db.backends.sqlite3'
'NAME': 修改为你的数据库文件的路径
保存配置,返回到项目根目录下,运行 python manage.py shell,执行如下命令:
>>> from django.db import connection
>>> cursor = connection.cursor()
这里,请确保你设置的数据库文件的目录已经的的确确存在了。如果运行以上命令没有出错的话,表明你的数据库配置是正确的。
接下来我们创建一个应用并将其命名为blog:
[danny@localhost dblog]$ python manage.py startapp blog
执行完成后可以发现目录下多出一个文件夹,这个目录里包含了这个app的模型和视图:
[danny@localhost blog]$ ls -l
total 12
-rw-r--r--. 1 danny danny 0 Nov 2 20:50 __init__.py
-rw-r--r--. 1 danny danny 57 Nov 2 20:50 models.py
-rw-r--r--. 1 danny danny 383 Nov 2 20:50 tests.py
-rw-r--r--. 1 danny danny 26 Nov 2 20:50 views.py
再次编辑settings.py,在INSTALLED_APPS里添加你的应用名称,即“blog”:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
)
三、创建模型:
一切的准备工作都已就绪,现在就该正式开始规划怎么存储博客的数据了,即模型的定义。
Django模型是用Python代码形式表述的数据在数据库中的定义。对数据层来说它等同于CREATE TABLE语句,只不过执行的是Python代码而不是SQL,而且还包含了比数据库字段定义更多的含义。Django用模型在后台执行SQL代码并把结果用Python的数据结构来描述。
回到我们的博客上,一个博客包含标题、作者、发表的时间、分类、标签等内容;而作者肯定有姓名和一些基本的联系方式;分类和标签则可以简单一些,只需要名字就足够了......
下面我们就来描述它:打开刚才创建的blog应用的models.py文件,并输入如下内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
from
django.db
import
models
class
Tag(models.Model):
tag_name
=
models.CharField(max_length
=
20
)
create_time
=
models.DateTimeField(auto_now_add
=
True
)
def
__unicode__(
self
):
return
self
.tag_name
class
Classification(models.Model):
name
=
models.CharField(max_length
=
20
)
def
__unicode__(
self
):
return
self
.name
class
Author(models.Model):
name
=
models.CharField(max_length
=
30
)
email
=
models.EmailField(blank
=
True
)
website
=
models.URLField(blank
=
True
)
def
__unicode__(
self
):
return
u
'%s'
%
(
self
.name)
class
Article(models.Model):
caption
=
models.CharField(max_length
=
30
)
subcaption
=
models.CharField(max_length
=
50
, blank
=
True
)
publish_time
=
models.DateTimeField(auto_now_add
=
True
)
update_time
=
models.DateTimeField(auto_now
=
True
)
author
=
models.ForeignKey(Author)
classification
=
models.ForeignKey(Classification)
tags
=
models.ManyToManyField(Tag, blank
=
True
)
content
=
models.TextField()
|
这里,每个模型相当于单个数据库表,而每个属性也就是这个表中的一个字段。每个数据模型都是 django.db.models.Model 的子类,它的父类 Model 包含了所有必要的和数据库交互的方法。其它的知识点这里就不说了,如果需要进一步了解,可以参考Django的官方文档。
保存并关闭,返回项目根目录下,执行 python manage.py validate,如果返回“0 errors found”,说明你的模型的语法和逻辑都正确。再执行 python manage.py sqlall blog,可以得到如下输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
BEGIN
;
CREATE
TABLE
"blog_tag"
(
"id"
integer
NOT
NULL
PRIMARY
KEY
,
"tag_name"
varchar
(20)
NOT
NULL
,
"create_time"
datetime
NOT
NULL
)
;
CREATE
TABLE
"blog_classification"
(
"id"
integer
NOT
NULL
PRIMARY
KEY
,
"name"
varchar
(20)
NOT
NULL
)
;
CREATE
TABLE
"blog_author"
(
"id"
integer
NOT
NULL
PRIMARY
KEY
,
"name"
varchar
(30)
NOT
NULL
,
"email"
varchar
(75)
NOT
NULL
,
"website"
varchar
(200)
NOT
NULL
)
;
CREATE
TABLE
"blog_article_tags"
(
"id"
integer
NOT
NULL
PRIMARY
KEY
,
"article_id"
integer
NOT
NULL
,
"tag_id"
integer
NOT
NULL
REFERENCES
"blog_tag"
(
"id"
),
UNIQUE
(
"article_id"
,
"tag_id"
)
)
;
CREATE
TABLE
"blog_article"
(
"id"
integer
NOT
NULL
PRIMARY
KEY
,
"caption"
varchar
(30)
NOT
NULL
,
"subcaption"
varchar
(50)
NOT
NULL
,
"publish_time"
datetime
NOT
NULL
,
"update_time"
datetime
NOT
NULL
,
"author_id"
integer
NOT
NULL
REFERENCES
"blog_author"
(
"id"
),
"classification_id"
integer
NOT
NULL
REFERENCES
"blog_classification"
(
"id"
),
"content"
text
NOT
NULL
)
;
CREATE
INDEX
"blog_article_cc846901"
ON
"blog_article"
(
"author_id"
);
CREATE
INDEX
"blog_article_337f0fda"
ON
"blog_article"
(
"classification_id"
);
COMMIT
;
|
很明显,你的模型已经变成了SQL语句,确认无误后,最后执行python manage.py syncdb即可将创建的模型同步至数据库。这里系统可能会提示你添加一个超级用户,按步骤添加即可,这个用户可以用于在之后登录Django的站点管理。
这一部分内容就到这里,如需系统学习,可以参考《The Django Book》第五章。
我的博客系统已经实现基本的功能了,现总结一下,顺便与大家分享。
写的不好,还请见谅。如果你有什么好的意见和建议,可以随时联系我,谢谢~
这一部分的主要内容包括:
· 基本的构思
· 开始一个项目
一、基本的构思:
博客系统,顾名思义,首要的目标就是实现对博客文章的管理,所以文章的增加、删除、修改是必不可少的,而文章又会包含有作者信息、发布时间以及正文等内容。对于访问者来说,能够方便快捷地浏览到你的文章是必不可少的,而为了实现交互性,还必须增加评论功能,以方便访问者对你的文章作出评价。
结合以上思想,对于一个简单的博客系统,必须要有以下的功能:
· 支持对文章的增加、修改和删除功能
· 一个全局浏览的主页和各文章的独立页面
· 实现评论功能
博客发表的多了,难免显得杂乱无章,因此增加个分类功能是个很好的选择。另外,标签也是每个博客必须的。
好了,基本就先这些,其它的需求在需要的时候再在之后慢慢增加就可以了...现在开始动工!
二、开始一个项目:
对于Django基础,《The Django Book》还是算一本不错的教程,推荐大家看看。这里运用到的知识在这本书中都能找到。
1.平台与安装:
我使用的是CentOS 6.3 + Python 2.6 + Django1.4,安装过程就不一一罗列了,如果不熟悉,在很多地方都能找到教程。
其次,Django的开发肯定要使用到数据库,所以务必安装相应的数据库软件,这里我使用的是sqlite3作为演示。
2.测试:
[danny@localhost ~]$ python
Python 2.6.6 (r266:84292, Sep 11 2012, 08:34:23)
[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> django.VERSION
(1, 4, 0, 'final', 0)
看到以上信息就说明你安装成功,可以开始创建自己的博客项目了。
3.创建一个项目:
在需要创建项目的目录下输入以下命令:
[danny@localhost ~]$ django-admin.py startproject dblog
这样就创建了一个名为“dblog”的项目,会在所选目录下生成一个目录并包含以下文件:
--->dblog
|--->dblog
| |--->__init__.py 让 Python 把该目录当成一个开发包 (即一组模块)所需的文件;
| |--->settings.py 该 Django 项目的设置或配置;
| |--->urls.py Django项目的URL设置;
| |--->wsgi.py
|--->manage.py 一种命令行工具,允许你以多种方式与该 Django 项目进行交互。
4.运行开发服务器:
[danny@localhost dblog]$ python manage.py runserver 0.0.0.0:8000
Validating models...
0 errors found
Django version 1.4, using settings 'dblog.settings'
Development server is running at
http://0.0.0.0:8000/
Quit the server with CONTROL-C.
其中runserver表明启动开发服务器,0.0.0.0:8000分别代表要绑定的地址和端口号。,这里0.0.0.0表示监听所有网络接口。
打开浏览器,输入Linux主机的地址,应可以看到如下信息:
如果访问不了,多数情况下应该是防火墙的设置问题,配置iptables开放相应的端口。
这一部分就到这里,如需系统的学习这部分内容,可参考《The Django Book》第一章。
首先,还是恭喜下自己终于有了一个自主设计的博客!虽然功能上还比较简单,但也算是小小的成果。
我是一个Python爱好者,如果你也是的话,那不难猜出我的博客是基于Django框架搭建的。这里罗列下当前实现的功能,也算是记录下目前为止的小小成果:
·支持文章的增加、修改和删除
·支持标签、分类
·集成百度Ueditor富文本编辑器
·支持Markdown、语法高亮
·支持基本的评论功能(我会在之后着重强化这一块,目前只是使用内置的评论框架)
·支持简单的博客搜索
·支持gravatar头像服务
·支持RSS订阅
当然,必须承认的是代码不总是我自己写的,特别是刚刚开始实际运用Django时还很生疏,不得不参考一下别人的经验,这里特别感谢cacique的实例教程:《Django简易博客开发》,从中收获颇多。
有了基础,接下来我还会继续学习,同时完善、优化这个博客系统 —— DannyBlog,在丰富功能的同时更进一步加深理解、锻炼自己。
上一节中,我们注重完成了博客UI的设计和主页的定制以及开启了Django站点管理以方便博客的管理,不过我们的主页并没有完善,其中很多东西和链接都还没加入,这将在以后来优化。
光有主页肯定是不行的。其实,对于很多博客来说主页只会显示博客的内容提要,而浏览全文则应该进入相应的博客展示页面,其中还包含访客的评论等内容。这就是这一节的主要内容,下面我们就一步步实现。
这一部分的主要内容:
· 使用Django评论库
· 使用模板继承
· 创建博客展示页
一、开启Django评论库:
这一节中,我们要创建博客的展示页,其中会包含评论部分,因此在这里我们首先开启Django内置的评论库,其可以很方便地帮助我们搭建一个评论系统。启动的步骤如下:
· 在settings.py中的INSTALLED_APPS中加入'django.contrib.comments';
· 同步数据库:
[danny@localhost dblog]$ python manage.py syncdb
Creating tables ...
Creating table django_comments
Creating table django_comment_flags
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
· 在dblog下的urls.py中添加如下代码:
urlpatterns = patterns('',
...
url(r'^comments/', include('django.contrib.comments.urls')),
...
)
再次打开Django站点管理界面可以看到增加了一条Comments,如下图所示:
现在即可正常使用了。
二、优化模板:
之前我们已经成功创建了主页的模板index.html,它工作的很好。但如果我们再创建一个模板,比如博客展示页,肯定会包含很多重复的内容,例如页眉的LOGO和导航栏以及页脚的一些内容等等。如果单纯的复制粘贴会造成大量的冗余代码,更好的方法是利用Django的模板继承。下面就让我们来优化一下以最大化的重用。
本质上来说,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载。
要使用继承,首先定义的应该是基础模板,其中包含各模板的公用部分,该框架之后将由子模板所继承。
在我们的模板中,头和尾都应该放在基础模板中让各页面直接继承,而中间的内容才是各页面自己定制的,所以将我们的基础模板定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<
html
xmlns
=
"http://www.w3.org/1999/xhtml"
>
<
head
>
<
meta
http-equiv
=
"Content-Type"
content
=
"text/html; charset=utf-8"
/>
<
title
>{% block title %}{% endblock %}
title
>
<
link
href
=
"/static/css/dblog.css"
rel
=
"stylesheet"
type
=
"text/css"
/>
head
>
<
body
>
<
div
class
=
"container"
>
<
div
class
=
"header"
>
<
div
id
=
"top"
>
<
a
href
=
"/blog/"
><
img
src
=
"/static/images/LOGO.png"
alt
=
"LOGO"
name
=
"logo"
width
=
"180"
height
=
"60"
id
=
"logo"
/>
a
>
<
div
id
=
"nav_div"
>
<
ul
id
=
"top_nav"
>
<
li
><
a
href
=
"/"
class
=
"a_normal"
>首页
a
>
li
>
<
li
><
a
href
=
"/rss/"
class
=
"a_normal"
>订阅
a
>
li
>
<
li
><
a
href
=
"/about/"
class
=
"a_normal"
>关于
a
>
li
>
ul
>
div
>
div
>
div
>
<
div
class
=
"content_body"
>
{% block content_body %}{% endblock %}
div
>
<
div
class
=
"footer"
>
<
div
id
=
"footer_logo"
>
div
>
<
div
id
=
"siteinfo"
>© 2007 - 2012 DannyWork Project
div
>
div
>
div
>
body
>
html
>
|
将其保存在templates目录下并命名为base.html,下面再修改index.html使其成为base.html的一个子模板:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
{% block title %}DannyBlog{% endblock %}
{% block content_body %}
<
div
class
=
"main_body"
>
{% for blog in blogs %}
<
div
class
=
"blog_body"
>
<
div
class
=
"blog_title"
><
a
href
=
"/detail/?id={{ blog.id }}"
>{{ blog.caption }}
a
>
div
>
<
div
class
=
"blog_info1"
>
<
span
class
=
"blog_info1_list"
>
<
span
class
=
"li_small_1"
>分类:<
a
href
=
"#"
>{{ blog.classification }}
a
>
span
>
<
span
class
=
"li_small_1"
>发表时间:{{ blog.publish_time|date:"Y-m-d H:i" }}
span
>
span
>
div
>
<
div
class
=
"blog_splitline"
>
div
>
<
div
class
=
"blog_description"
>{{ blog.content }}
div
>
<
div
class
=
"blog_info2"
>
<
span
class
=
"blog_info2_list"
>
<
span
class
=
"li_small_2"
>标签:{% for tag in blog.tags.all %}<
a
href
=
"#"
>{{ tag.tag_name }}
a
>{% endfor %}
span
>
span
>
div
>
div
>
{% endfor %}
div
>
{% endblock %}
|
再次访问我们的主页,是不是和以前一样呢?那是肯定的,说明模板继承已经见成效了,下面我们来看看其中的一些重点:
在加载index.html模板时,模板引擎发现了{% extends %}标签,注意到该模板是一个子模板。模板引擎立即装载其父模板,即base.html。此时,模板引擎注意到base.html中的两个{% block %}标签,并用子模板的内容替换这些block。因此,引擎将会使用我们在{ block title %}中定义的标题,对{% block content %}也是如此。所以,网页标题一块将由{% block title %}替换,同样地,网页的内容一块将由{% block content %}替换。注意当子模板没有定义父模板中的block块时,模板系统将使用在父模板中定义的值。 父模板 {% block %} 标签中的内容总是被当作一条退路。继承并不会影响到模板的上下文。 换句话说,任何处在继承树上的模板都可以访问到你传到模板中的每一个模板变量。
三、创建博客展示页:
通过上一步中对模板的优化,现在我们可以很方便的创建博客展示页的模板了,其代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
{% block title %} {{ blog.caption }} - DannyBlog {% endblock %}
{% load comments %}
{% block content_body %}
<
div
class
=
"main_body"
>
<
div
class
=
"blog_body"
>
<
div
class
=
"blog_title"
>{{ blog.caption }}
div
>
<
div
class
=
"blog_info1"
>
<
span
class
=
"blog_info1_list"
>
<
span
class
=
"li_small_1"
>分类:<
a
href
=
"#"
>{{ blog.classification }}
a
>
span
>
<
span
class
=
"li_small_1"
>作者:<
a
href
=
"#"
>{{ blog.author }}
a
>
span
>
<
span
class
=
"li_small_1"
>发表时间:{{ blog.publish_time|date:"Y-m-d H:i" }}
span
>
span
>
div
>
<
div
class
=
"blog_splitline"
>
div
>
<
div
class
=
"blog_description"
>{{ blog.content }}
div
>
div
>
<
div
class
=
"comments"
>
<
a
name
=
"blog_comments"
id
=
"comments"
>
a
>
{% get_comment_count for blog as comment_count %}
<
div
class
=
"comments_nav"
>评论({{ comment_count }})
div
>
{% ifequal comment_count 0 %}
<
div
class
=
"comments_body"
>
<
div
class
=
"comment_container"
>没有评论
div
|