Django个人博客开发(二)DjangoPythonDjango博客系统
前一部分,我们已经成功创建了博客项目,是时候正是施工了...
这一部分的主要内容:
· 了解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文件,并输入如下内容:
1234567891011121314151617181920212223242526272829303132 | 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,可以得到如下输出:
12345678910111213141516171819202122232425262728293031323334353637383940 | 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》第五章。
29OCTDjango个人博客开发(一)DjangoPythonDjango博客系统我的博客系统已经实现基本的功能了,现总结一下,顺便与大家分享。
写的不好,还请见谅。如果你有什么好的意见和建议,可以随时联系我,谢谢~
这一部分的主要内容包括:
· 基本的构思
· 开始一个项目
一、基本的构思:
博客系统,顾名思义,首要的目标就是实现对博客文章的管理,所以文章的增加、删除、修改是必不可少的,而文章又会包含有作者信息、发布时间以及正文等内容。对于访问者来说,能够方便快捷地浏览到你的文章是必不可少的,而为了实现交互性,还必须增加评论功能,以方便访问者对你的文章作出评价。
结合以上思想,对于一个简单的博客系统,必须要有以下的功能:
· 支持对文章的增加、修改和删除功能
· 一个全局浏览的主页和各文章的独立页面
· 实现评论功能
博客发表的多了,难免显得杂乱无章,因此增加个分类功能是个很好的选择。另外,标签也是每个博客必须的。
好了,基本就先这些,其它的需求在需要的时候再在之后慢慢增加就可以了...现在开始动工!
二、开始一个项目:
对于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》第一章。
26OCTDannyBlog!心得与分享PythonDjango博客系统个人网站UEditorgravatar首先,还是恭喜下自己终于有了一个自主设计的博客!虽然功能上还比较简单,但也算是小小的成果。
我是一个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的模板继承。下面就让我们来优化一下以最大化的重用。
本质上来说,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载。
要使用继承,首先定义的应该是基础模板,其中包含各模板的公用部分,该框架之后将由子模板所继承。
在我们的模板中,头和尾都应该放在基础模板中让各页面直接继承,而中间的内容才是各页面自己定制的,所以将我们的基础模板定义如下:
123456789101112131415161718192021222324252627282930313233 | < 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 > <!-- end .header --> </ 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 > <!-- end .footer --> </ div > <!-- end .container --> </ div > </ body > </ html > |
将其保存在templates目录下并命名为base.html,下面再修改index.html使其成为base.html的一个子模板:
12345678910111213141516171819202122232425 | {% 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 %} 标签中的内容总是被当作一条退路。继承并不会影响到模板的上下文。 换句话说,任何处在继承树上的模板都可以访问到你传到模板中的每一个模板变量。
三、创建博客展示页:
通过上一步中对模板的优化,现在我们可以很方便的创建博客展示页的模板了,其代码如下:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 | {% 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 > {% else %} {% get_comment_list for blog as comments %} < div class = "comments_body" > {% for comment in comments %} < div class = "comment_container" > < div class = "comment_id" >< a href = "{{ comment.user_url }}" >< img src = "/static/images/hp.jpg" width = "42" height = "42" /></ a ></ div > < div class = "cmt_user_info" > < span class = "li_small_2" >{{ comment.user_name }}</ span > < span class = "li_small_2" >{{ comment.submit_date|date:"Y-m-d H:i"}}</ span > < span class = "reply_comment" id = "{{ comment.user_name }}" >< a href = "#newcomment" >回复</ a ></ span > </ div > < div id = "comment_content" >{{ comment.comment }}</ div > </ div > {% endfor %} {% endifequal %} </ div > < div class = "comments_nav" >新的评论</ div > {% get_comment_form for blog as blog_form %} < div class = "comments_body" > < div class = "comment_form" > < form class = "form-horizontal" action = "{% comment_form_target %}" method = "post" id = "cmt_sub_form" > {% csrf_token %} {{ blog_form.object_pk }} {{ blog_form.content_type }} {{ blog_form.timestamp }} {{ blog_form.site }} {{ blog_form.submit_date }} {{ blog_form.security_hash }} < div class = "control-group" > < label class = "control-label" for = "id_name" >用户名: </ label > < div class = "controls" > < input type = "text" id = "id_name" class = "input-xlarge" name = "name" placeholder = "请输入您的用户名" value = "{{ user.username }}" /> </ div > </ div > < div class = "control-group" > < label class = "control-label" for = "id_email" >E-mail: </ label > < div class = "controls" > < input class = "input-xlarge" id = "id_email" type = "email" name = "email" placeholder = "请输入您的邮箱地址" value = "{{ user.email }}" /> </ div > </ div > < div class = "control-group" > < label class = "control-label" for = "id_email" >网址: </ label > < div class = "controls" > < input class = "input-xlarge" id = "id_url" type = "url" name = "url" placeholder = "请输入您的网址" value = "{{ user.url }}" /> </ div > </ div > < a name = "newcomment" id = "newcomment" ></ a > < div class = "control-group" > < label class = "control-label" for = "id_comment" >评论: </ label > < div class = "controls" > < textarea class = "input-xlarge comment" id = "id_comment" name = "comment" placeholder = "请输入评论内容" ></ textarea > </ div > </ div > < p style = "display:none;" >< label for = "id_honeypot" >如果你在该字段中输入任何内容,你的评论就会被视为垃圾评论。</ label > < input type = "text" name = "honeypot" id = "id_honeypot" ></ p > < div class = "controls" > < div class = "form-actions" > < input class = "btn btn-info" id = "submit_btn" type = "submit" name = "submit" value = "提交" /> < input type = "hidden" name = "next" value = "/detail/?id={{ blog.id }}" /> </ div > </ div > </ form > </ div > </ div > </ div > </ div > {% endblock %} |
这里,我们需要了解一些基础:
· 在模型中使用Django评论库,必须加载自定义标签:{% load comments %};
· 获取评论数:{% get_comment_count for entry as comment_count %};
· 获取评论对象的列表:{% get_comment_list for event as comment_list %},之后遍历该列表即可依次读取评论;
· 对于评论表单,如果希望对其进行自定义,就必须使用get_comment_form来获取form对象并应用于模型:{% get_comment_form for event as form %};
· 在form的action属性中,需要使用comment_form_target,这可以确保获得正确的表单提交地址:
<form action="{% comment_form_target %}" method="post">;
· 如果希望自定义提交后的跳转,可以在表单内包含一个隐藏的input元素:
<input type="hidden" name="next" value="{% url my_comment_was_posted %}"/>;
· 还有一个需要关注的就是{% csrf_token %}:
Django默认开启了csrf中间件以提升安全性,所以需要在form表单内加入该语句,否则会导致提交失败(403)。
· 如果用户提交的表单有误,comments库会默认加载源码中的comments/preview.html这个模板并返回要求用户修改,可以对其进行自定义以满足自己网站的需求。
同样,将其保存在templates目录下,并命名为detail.html。接下来修改urls.py,加入如下内容:
12 | url(r '^detail/$' , 'blog_detail' ), ) |
最后打开blog下的views.py,增加相应的视图函数:
1234567891011 | def blog_detail(request): if request.method = = 'GET' : id = request.GET.get( 'id' , ''); try : blog = Article.objects.get( id = id ) except Article.DoesNotExist: raise Http404 return render_to_response( "detail.html" , { "blog" : blog}, context_instance = RequestContext(request)) else : raise Http404 |
这里,我们通过关键字id来获知用户希望查阅的文章。
到这里一个简单的展示页就算完成了,访问我们的主页,并点击标题的链接应该就可以跳转到指定的博客展示页面:
尝试评论一下:
It works!
这一小节内容就结束了,如需系统学习,可以参考《The Django Book》第四、七、九章以及Django官方文档内有关comments库和csrf的介绍。
6NOVDjango个人博客开发(四)DjangoPythonDjango博客系统经过前面三节的努力,我们的博客雏形已经建立起来了,从这一节开始,我们的主要任务就放在基本功能的实现。
这一部分的主要内容:
· 完善模板
· 静态文件的使用
· Django站点管理
一、美化站点与静态文件:
之前我们构建的模板,如果要说敷衍了事,也的确是。因为那既是一个没有头没有尾的残缺页面,也没有任何的美化效果,所有的东西都是很牵强的从上到下依次摆在上面。这很明显不符合一个站点的要求。
一个网站确确实实需要设计、美化,形象很重要嘛。所以在继续之前,我认为你还是应该好好构思一个你的博客要怎么排版,然后在PS等工具中做出效果图。当然,如果不愿意自己设计美化,也可以使用如Bootstrap这样的框架来达到相同的目的。这里,我为了方便,就以我自己的页面设计作为例子继续讲述。
完成页面的设计之后,肯定会得到如图片、CSS样式表、JS脚本等静态文件,要在Django中正确使用这些文件,我们需要做一些配置。
首先,回到项目的根目录,新建一个文件夹并命名为static,现在,你的项目目录应该包含这些文件(目录)了:
[danny@localhost dblog]$ ls -l
total 20
drwxrwxr-x. 2 danny danny 4096 Nov 6 00:37 blog
drwxrwxr-x. 2 danny danny 4096 Nov 2 21:35 data
drwxrwxr-x. 2 danny danny 4096 Nov 6 00:38 dblog
-rwxr-xr-x. 1 danny danny 248 Oct 29 00:51 manage.py
drwxrwxr-x. 2 danny danny 4096 Nov 6 21:11 static
drwxrwxr-x. 2 danny danny 4096 Nov 6 00:34 templates
进入到static目录,新建三个子目录,分别命名为images、js、css,。然后打开settings.py,添加如下内容:
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
'/home/danny/dblog/static',
)
别忘记将路径该为你自己的,而且这里我故意未删除原有的注释:一定要使用绝对路径。
保存并关闭,再打开urls.py文件,加入如下内容:
123 | (r '^static/(?P<path>.*)$' , 'django.views.static.serve' , { 'document_root' : '/home/danny/dblog/static' }), ) |
现在你就可以放心大胆的将静态文件放在对应的文件夹中了。
二、完善“残缺的”模板:
我的主页设计好了,正如你看到的这样,现在我们就把它加入到index.html中:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 | < html xmlns = "http://www.w3.org/1999/xhtml" > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" /> < title >DannyBlog</ 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 = "#" class = "a_normal" >订阅</ a ></ li > < li >< a href = "#" class = "a_normal" >关于</ a ></ li > </ ul > </ div > </ div > <!-- end .header --> </ div > < div class = "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 > </ div > < div class = "footer" > < div id = "footer_logo" ></ div > < div id = "siteinfo" >© 2007 - 2012 DannyWork Project</ div > <!-- end .footer --> </ div > <!-- end .container --> </ div > </ body > </ html > |
现在再次打开浏览器访问我们的项目主页,应该看着好多了,不过还没有内容,下面我们就来添加点博客进去。
三、使用Django站点管理:
虽然刚才说到为我们的博客添加点文章好充充数预览下效果,不过要怎么添加呢?到目前为止,好像我们还没有这方面内容的积累。也许你会想,可以通过之前的模型操作方法直接向数据库中添加数据?不过这种操作方法太不现实了。更理想的是我们需要一个后台的管理界面,可以方便的对网站数据进行增加、更改、删除等操作。不过自己开发一个这样的管理界面实在是过于繁琐了,还好Django为我们提供了一个自动管理界面,可以很方便的开启使用。
Django自动管理工具是django.contrib的一部分。django.contrib是一套庞大的功能集,它是Django基本代码的组成部分,Django框架就是由众多包含附加组件(add-on)的基本代码构成的。你可以把django.contrib看作是可选的Python标准库或普遍模式的实际实现。它们与Django捆绑在一起,这样你在开发中就不用“重复发明*”了。
让我们马上行动吧,打开settings.py文件并检查或修改以下项:
· 将'django.contrib.admin'加入setting的INSTALLED_APPS配置中并确保之中还包含'django.contrib.auth','django.contrib.contenttypes'和'django.contrib.sessions';
· 确保MIDDLEWARE_CLASSES包含 'django.middleware.common.CommonMiddleware'、 'django.contrib.sessions.middleware.SessionMiddleware' 和 'django.contrib.auth.middleware.AuthenticationMiddleware'。
回到项目根目录,运行python manage.py syncdb,如果之前添加过超级用户,这里会直接跳过,否则会要求你添加,按步骤操作即可。
最后再打开urls.py,增加如下内容:
1234567 | admin.autodiscover() urlpatterns = patterns('', # ... url(r '^admin/' , include(admin.site.urls)), # ... ) |
这样就完成了,打开浏览器(如果你停止了开发服务器,请重新运行)并访问http://django_server_ip:8000/admin/,即可看到Django站点管理的登录界面:
输入之前创建的超级用户的用户名和密码即可登录:
不过我们自己的模型貌似还没在这里出现。打开blog项目的目录,新建admin.py文件并输入如下内容:
1234567891011121314151617 | from blog.models import Tag, Author, Article, Classification class AuthorAdmin(admin.ModelAdmin): list_display = ( 'name' , 'email' , 'website' ) search_fields = ( 'name' ,) class ArticleAdmin(admin.ModelAdmin): list_display = ( 'caption' , 'subcaption' , 'classification' , 'author' , 'publish_time' , 'update_time' ) list_filter = ( 'publish_time' ,) date_hierarchy = 'publish_time' ordering = ( '-publish_time' ,) filter_horizontal = ( 'tags' ,) admin.site.register(Article, ArticleAdmin) admin.site.register(Author, AuthorAdmin) admin.site.register(Tag) admin.site.register(Classification) |
重启一下开发服务器,再次访问管理页面,你会发现需要的东西出现了。
这里我们新建了一个AuthorAdmin类和ArticleAdmin类,它是从django.contrib.admin.ModelAdmin派生出来的子类,保存着一个类的自定义配置,以供管理工具使用。我们自定义了一项:list_display,它是一个字段名称的元组,用于列表显示;而search_fields会在页面顶端加入一个搜索栏,。当然,这些添加的字段名称必须是模块中有的。我们修改了admin.site.register()调用,在Author后面添加了AuthorAdmin。你可以这样理解:用AuthorAdmin选项注册Author模块。admin.site.register()函数接受一个ModelAdmin子类作为第二个参数。如果你忽略第二个参数,Django将使用默认的选项。
其它就不一一列举说明了,需要了解更多的内容可以参考Django官方文档。
现在就让我们利用这个管理系统添加一个新的博客,内容就随便你啦,然后刷新主页,是不是出现了呢?
这一小节内容就结束了,如需系统学习,可以参考《The Django Book》第三、四、六章的内容。
5NOVDjango个人博客开发(三)DjangoPythonDjango博客系统模型已经成功完成, 这一节让我们来继续其它几个基础部分的创建。
这一部分的主要内容:
· 模型的基本操作
· 第一个视图
· 模板基础
· URLConf初探
一、模型(续) —— 基本的操作:
上一节中,我们已经成功建立了几个需要的模型,这里就简单说一下基本的模型操作:
· 插入数据:new_blog = Article(caption='my blog title', author='author', classification='classification', content = 'blog content')
· 保存数据:new_blog.save()
· 获取数据 / 更新数据:id = new_blog.id / new_blog.caption = 'new title'
· 选择表中的所有对象:blogs = Article.objects.all()
· 过滤数据:specified_blogs = Article.objects.filter(classification='classification')
· 获取单个对象:blog = Article.objects.get(name='my blog title')
· 排序:blogs = Article.objects.order_by('name')
· 删除数据:blog.delete()
其中objects属性被称为管理器,其管理着所有针对数据包含、还有最重要的数据查询的表格级操作。所有的模型都自动拥有一个objects管理器。
二、第一个视图:
了解了模型的操作方法后,我们可以开始建立视图了。第一个视图,我们要做的是将已经发布的博客展示出来,以我自己的主页为例,包括博客的标题、分类、发布时间、内容以及标签(评论等之后再说)。
视图包含存取模型及调取恰当模板的相关逻辑。要实现将所有的Blog显示出来,首先需要利用模型操作从数据库中提取所有的Blog,然后提交给模板(这是之后的内容)形成所需的页面。
打开blog应用下的views.py,并输入以下内容:
12345678 | from blog.models import Article, Tag, Classification from django.shortcuts import render_to_response from django.template import RequestContext def blog_list(request): blogs = Article.objects. all ().order_by( '-publish_time' ) return render_to_response( 'index.html' , { "blogs" : blogs}, context_instance = RequestContext(request)) |
· 第一行从models.py中导入了之前创建的模型;
· 在函数内部,我们利用模型的操作方法分别从Article、Tag、Classification中获取了所有的blog对象、tag对象和classification对象;
· 最后调用了render_to_response方法,它的第一个参数是要使用的模板名称;第二个参数是为该模板创建 Context 时所使用的字典,可以理解为要传入模板的参数;而RequestContext默认地在模板context中加入了一些变量,如HttpRequest对象或当前登录用户的相关信息。
三、模板的使用:
模板是一个文本,用于分离文档的表现形式和内容。 模板定义了占位符以及各种用于规范文档该如何显示的各部分基本逻辑(模板标签)。模板通常用于产生HTML。
在上面的视图函数中,我们在render_to_response的第一个参数中指定了“index.html”,但django要怎么找到它呢?我们需要做一些配置。
首先,回到项目的根目录,新建一个文件夹并命名为templates。然后打开项目的配置文件settings.py,并找到以下行:
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
把我们之前所创建的文件夹的绝对路径加入进TEMPLATE_DIRS里,如:
TEMPLATE_DIRS = (
'/home/danny/dblog/templates',
)
注意这里必须使用绝对路径。保存并关闭,进入到templates目录,新建文件"index.html"并输入如下内容:
12345678910111213141516171819 | {% for blog in blogs %} < div class = "blog_body" > < div class = "blog_title" >< a href = "/blog/detail/?id={{ blog.id }}" >{{ blog.caption }}</ a ></ div > < div class = "blog_info" > < ul class = "blog_info_list" > < li >分类:{{ blog.classification }}</ li > < li >发表时间:{{ blog.publish_time|date:"Y-m-d H:i" }}</ li > < li >标签: {% for tag in blog.tags.all %} {{ tag.tag_name }} {% endfor %} </ li > </ ul > </ div > < div class = "blog_description" > {{ blog.content }} </ div > </ div > {% endfor %} |
请注意,这不是一个完整的网页,这只是刚开始的演示,完整的页面我们在之后再一步步创建。
其中,用两个大括号括起来的文字(如{{ blog.caprion }})称为变量,这意味着在此处插入变量的值;
被大括号和百分号包围的文本(如{% for blog in blogs %})是模板标签,即通知模板系统完成某些工作;
在输出“发表时间”时,在变量后还跟着一个管道符“|”,这是过滤器,是一种便捷的转换变量输出格式的方式。
要了解更多关于模板的知识,请参考官方文档。
接着,我们还需要一个步骤,那就是指定应该怎样才能访问到这个页面。
四、URLConf:
现在,如果你再运行:python manage.py runserver,你还将看到Django的欢迎页面,而不会出现我们希望显示的博客页面。那是因为我们的项目还对blog_list这个视图一无所知。我们需要通过一个详细描述的URL来显式的告诉它并且激活这个视图。为了绑定视图函数和URL,我们使用URLconf。
URLconf就像是Django所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表。你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。
现在,让我们打开项目目录下的urls.py,并添加我们之前创建的blog_list:
123 | urlpatterns = patterns('', url(r '^$' , 'blog.views.blog_list' , name = 'blog_list' ), ) |
注意,这里我为了节约篇幅删除了默认的一些注释,实际中你应该保留它们,其中包含了一些Django中常用的功能,仅仅只需去掉这些注释就可以开启这些功能。
五、预览到目前为止的成果:
现在,再次运行 python manage.py runserver 0.0.0.0:8000,并在浏览器中访问,可以看到以下页面:
可以发现,只显示出“My Blog List”,因为我们还没在数据库中添加任何博客。
这只是一个简单的演示,我们之前的操作还存在太多的漏洞需要修补,这就是我们接下来需要做的。
这一部分内容就到这里,如需系统学习,可以参考《The Django Book》第三、四章内容。