你要提醒众人,叫他们顺服作官的、掌权的,遵他的命,预备行各样的善事。不要毁谤,不要争竞,总要和平,向众人大显温柔。我们从前也是无知,悖逆,受迷惑,服侍各样私欲和宴乐,常存恶毒、嫉妒的心,是可恨的,又是彼此相恨。但到了神我们救主的恩慈和他向人所施的慈爱显明的时候,他便救了我们,并不是我们自己所行的义,乃是照着他的怜悯,藉着重生的洗和圣灵的更新。(TITUS 3:1-5)
用tornado做网站(1)
从现在开始,做一个网站,当然,这个网站只能算是一个毛坯的,可能很简陋,但是网站的主要元素,它都会涉及到,读者通过此学习,能够了解网站的开发基本结构和内容,并且对前面的知识可以有综合应用。
基本结构
下面是一个网站的基本结构
前端
这是一个不很严格的说法,但是在日常开发中,都这么说。在网站中,所谓前端就是指用浏览器打开之后看到的那部分,它是呈现网站传过来的信息的界面,也是用户和网站之间进行信息交互的界面。撰写前端,一般使用HTML/CSS/JS,当然,非要用python也不是不可以(例如上节中的例子,就没有用HTML/CSS/JS),但这势必造成以后维护困难。
MVC模式是一个非常好的软件架构模式,在网站开发中,也常常要求遵守这个模式。请阅读维基百科的解释:
MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
MVC模式最早由Trygve Reenskaug在1978年提出,是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一种软件设计模式。MVC模式的目的是实现一种动态的程式设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,此模式通过对复杂度的简化,使程序结构更加直观。软件系统通过对自身基本部分分离的同时也赋予了各个基本部分应有的功能。专业人员可以通过自身的专长分组:
- (控制器 Controller)- 负责转发请求,对请求进行处理。
- (视图 View) - 界面设计人员进行图形界面设计。 -(模型 Model) - 程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。
所谓“前端”,就对大概对应着View部分,之所以说是大概,因为MVC是站在一个软件系统的角度进行划分的,上图中的前后端,与其说是系统部分的划分,不如严格说是系统功能的划分。
前端所实现的功能主要有:
- 呈现内容。这些内容是根据url,由后端从数据库中提取出来的。前端将其按照一定的样式呈现出来。另外,有一些内容,不是后端数据库提供的,是写在前端的。
- 用户与网站交互。现在的网站,这是必须的,比如用户登录。当用户在指定的输入框中输入信息之后,该信息就是被前端提交给后端,后端对这个信息进行处理之后,在一般情况下都要再反馈给前端一个处理结果,然后前端呈现给用户。
后端
这里所说的后端,对应着MVC中的Controller和Model的部分或者全部功能,因为在我们的图中,“后端”是一个狭隘的概念,没有把数据库放在其内。
不在这些术语上纠结。
在我们这里,后端就是用python写的程序。主要任务就是根据需要处理由前端发过来的各种请求,根据请求的处理结果,一方面操作数据库(对数据库进行增删改查),另外一方面把请求的处理结果反馈给前端。
数据库
工作比较单一,就是面对后端的python程序,任其增删改查。
关于python如何操作数据库,在本教程的第贰季第柒章中已经有详细的叙述,请读者阅览。
一个基本框架
上节中,显示了一个只能显示一行字的网站,那个网站由于功能太单一,把所有的东西都写到一个文件中。在真正的工程开发中,如果那么做,虽然不是不可,但开发过程和后期维护会遇到麻烦,特别是不便于多人合作。
所以,要做一个基本框架。以后网站就在这个框架中开发。
建立一个目录,在这个目录中建立一些子目录和文件。
/.
|
handlers
|
methods
|
statics
|
templates
|
application.py
|
server.py
|
url.py
这个结构建立好,就摆开了一个做网站的架势。有了这个架势,后面的事情就是在这个基础上添加具体内容了。当然,还可以用另外一个更好听的名字,称之为设计。
依次说明上面的架势中每个目录和文件的作用(当然,这个作用是我规定的,读者如果愿意,也可以根据自己的意愿来任意设计):
- handlers:我准备在这个文件夹中放前面所说的后端python程序,主要处理来自前端的请求,并且操作数据库。
- methods:这里准备放一些函数或者类,比如用的最多的读写数据库的函数,这些函数被handlers里面的程序使用。
- statics:这里准备放一些静态文件,比如图片,css和javascript文件等。
- templates:这里放模板文件,都是以html为扩展名的,它们将直接面对用户。
另外,还有三个python文件,依次写下如下内容。这些内容的功能,已经在上节中讲过,只是这里进行分门别类。
url.py文件
#!/usr/bin/env python
# coding=utf-8
"""
the url structure of website
"""
import sys #utf-8,兼容汉字
reload(sys)
sys.setdefaultencoding("utf-8")
from handlers.index import IndexHandler #假设已经有了
url = [
(r'/', IndexHandler),
]
url.py文件主要是设置网站的目录结构。from handlers.index import IndexHandler
,虽然在handlers文件夹还没有什么东西,为了演示如何建立网站的目录结构,假设在handlers文件夹里面已经有了一个文件index.py,它里面还有一个类IndexHandler。在url.py文件中,将其引用过来。
变量url指向一个列表,在列表中列出所有目录和对应的处理类。比如(r'/', IndexHandler),
,就是约定网站根目录的处理类是IndexHandler,即来自这个目录的get()或者post()请求,均有IndexHandler类中相应方法来处理。
如果还有别的目录,如法炮制。
application.py文件
#!/usr/bin/env python
# coding=utf-8
from url import url
import tornado.web
import os
settings = dict(
template_path = os.path.join(os.path.dirname(__file__), "templates"),
static_path = os.path.join(os.path.dirname(__file__), "statics")
)
application = tornado.web.Application(
handlers = url,
**settings
)
从内容中可以看出,这个文件完成了对网站系统的基本配置,建立网站的请求处理集合。
from url import url
是将url.py中设定的目录引用过来。
setting引用了一个字典对象,里面约定了模板和静态文件的路径,即声明已经建立的文件夹"templates"和"statics"分别为模板目录和静态文件目录。
接下来的application就是一个请求处理集合对象。请注意tornado.web.Application()
的参数设置:
tornado.web.Application(handlers=None, default_host='', transforms=None, **settings)
关于settings的设置,不仅仅是文件中的两个,还有其它,比如,如果填上debug = True
就表示出于调试模式。调试模式的好处就在于有利于开发调试,但是,在正式部署的时候,最好不要用调试模式。其它更多的settings可以参看官方文档:tornado.web-RequestHandler and Application classes
server.py文件
这个文件的作用是将tornado服务器运行起来,并且囊括前面两个文件中的对象属性设置。
#!/usr/bin/env python
# coding=utf-8
import tornado.ioloop
import tornado.options
import tornado.httpserver
from application import application
from tornado.options import define, options
define("port", default = 8000, help = "run on the given port", type = int)
def main():
tornado.options.parse_command_line()
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
print "Development server is running at http://127.0.0.1:%s" % options.port
print "Quit the server with Control-C"
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
此文件中的内容,在上节已经介绍,不再赘述。
如此这般,就完成了网站架势的搭建。
后面要做的是向里面添加内容。