Build Web Applications with Flask试译2

第二章 第一个程序,能有多难呐?

整个上一章没写一行代码,现在你需要这个啦,对不?本章,我们将编写第一个程序并逐行解释。同时也包含如何设置开发环境,使用何种工具进行开发,以及如何在程序中使用HTML。

Hello World程序

在学习新编程语言时,我们所写的第一个程序通常都是HelloWorld,通过最小的代码启动一个程序并输出文字"Hello World!"。让我们也用Flask来实现它吧!

预备和工具

首先,确认一下我们正确配置了开发环境。本课程中,我假定你的操作系统是Debian类Linux发行版,如Mint(http://www.linuxmin.com),或者 Ubuntu(http://ubuntu.com)。其中所有的命令操作都将基于这些系统。

接下来,我们先通过apt-get命令安装必需的Debian包:

 sudo apt-get install python-dev python-pip

这将安装python开发工具和编译所需要的python库,以及pip:一个灵巧耗用的工具,你可以用它通过命令行来安装自己需要的python包。用起来吧!首先我们安装一个环境管理工具:

sudo pip install virtualenvwrapper
echo "source /usr/local/bin/birtualenvwrapper.sh" >> ~/.bashrc

解释一下上面的操作:sudo 告诉系统我们需要管理员权限来运行后面的命令,pip是默认的python包管理工具,可以帮我们安装virtualenvwrapper包。第二个命令把命令添加到virtualenvwrapper.sh并加载到当前控制台,以便于在当前shell中运行。

设置虚拟环境

所谓虚拟环境就是python用来隔离不同环境中的开发包的一种方法:它意味着你可以轻松的管理各类包依赖。想象一下,你要定义一个最小的只包含必要的开发包的项目,虚拟环境就可以完美地让你进行测试和输出必需的包。我们将在后面再研究它。现在,按下键盘上的Ctrl+Shift+T打开一个新的终端,创建我们的helloworld环境,如下:

mkvirtualenv hello
pip install flask

第一行,创建了名为'hello'的虚拟环境,且自动加载环境变量到当前终端。你可以输入deactivate命令关闭它,也可以通过以下命令来加载激活这一环境:

 workon hello #需要的话,用其它的环境名来替换hello

第二行告诉pip去安装Flask包到当前虚拟环境里,在本例中是把flask包安装到hello虚拟环境里。

理解“Hello World”程序

设定完虚拟环境,那我们用啥来编写出漂亮的代码呢?一个编辑器或者是一个IDE(集成开发环境)?如果你的预算低,那么可以尝试一下LightTable editor编辑器(http://lighttable.com)。免费、快速并且易于使用(Ctrl+空格可以看到所有可用选项),并且它还支持工作空间。这个价格没有更好的了。如果你很幸运有200美刀的预算(或者你拥有自由许可,那就不需要犹豫,直接入手PyCharm IDE吧(https://www.jetbrains.com/pycharm/buy/),它几乎是最好的Python Web开发的IDE了。现在,我们继续。

创建一个文件夹来存放你的项目文件(不是必须的,但如果你这么做了,大家会更喜欢你的),如下:
mkdir hello_world
进入新文件夹后创建文件 main.py:

cd hello_world
touch main.py

main.py文件将包含整个“Hello World”程序代码。其内容应该如下所示:

#coding:utf-8
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__=="__main__":
    app.run()

哇塞!就是敲了几个字,对吧?不?哈哈好吧,我明白的。那么,我们刚才都做了什么?
第一行标明我们的main.py文件使用utf-8编码。酷伙计们都这么做,所以别对你的英语非母语的朋友太苛刻。在你的所有python文件中使用它(这样可以在大型项目中帮你预防令人讨厌的低级错误)。
第二行和第三行中,我们导入了Flask类并将其实例化。我们程序的名字是“app”。几乎所有的都跟它(app)相关联:视图(view)、蓝图(blueprint) ,配置(config)等等。“__name__”参数是必需的,用来告诉程序从何处查找资源,诸如静态内容或模板等。

为了创建“Hello World”,在用户访问web程序(使用浏览器或别的什么咚咚)的时候,我们需要告诉Flask实例如何应答。因此,Flask拥有叫做路由(route)的东西。

路由,就是是Flask读取请求头部并决定那个视图(view,译:Flask的视图并不是MVC意义上的视图view,而是类似MVC的控制器Controler)来应答此请求的方法。它首先分析被请求的URL的路径部分,然后查找是哪个路由被注册到这个路径上。

在HelloWorld例子中,第五行,我们使用路由装饰符来把hello函数注册到根路径("/")。每次当程序接收到路径是“/”的请求时,hello函数就会被调用来应答这个请求。下面的片断展示了如何检查URL中的路径:

from urlparse import urlparse
parsed = urlparse("http://www.google.com/")
assert parsed.path=="/"

你也可以将多个路由映射到同一个函数上,如下:

@app.route('/') 
@app.route('/index')
def hello():
    return "Hello World"

本例中,“/”和“/index”两个路径都被映射到hello视图函数上。

第六行和第七行,我们完成了应答请求的函数。注意: 它没有参数并且回复友好字符串。它之所以不需要参数是因为请求数据(如被提交的表单form)可以通过线程安全的变量“request”来访问,这点我们将在上传章节中进行详细讨论。

关于应答(response),Flask可以多种格式应答请求。在我们的例子中,我们以纯文本应答,但我们还可以JSON或HTML格式应答。

第九行和第十行比较简单,它们检查main.py是以独立脚本还是以模块的形式被调用。如果是脚本,它就会运行内建的开发服务器。让我们试一下:
python main.py

你的终端将会有类似于下面的输出:
Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

在你的浏览器中打开这个地址(http://127.0.0.1:5000/ )就会看到,我们的程序已经正常工作了。

以脚本的形式调用main.py非常简单、便于设置。通常,你只需要安装Flask-Script扩展就可以调用开发服务器。

如果你把main.py作为模块调用,只需要把它用如下代码导入即可:
from main import what_I_want

在测试代码的时候,你可能需要经常这样导入一个app的工厂函数。
这基本上就是我们“Hello World”程序全部需要解释和理解的东西了。目前程序的缺憾就是没有有趣的因素,所以让我们添加上点东西,让程序更有意思些。添加上HTML,CSS,和JavaScript可以更美观些,让我们试试吧。

响应HTML页面

首先,要让我们的hello函数用HTML应答,只需要做如下的更改:

def hello():
    return "<html><head><title>Hi there!</title></head>
            <body>Hello world!</body></html>",200

在上面的例子中,hello函数返回了HTML格式的字符串以及一个数字。字符串默认情况下被解析为HTML,而200则是表示应答成功的HTTP代码。默认情况下也是返回200。

如果你按F5刷新浏览器,你将注意到页面没有变化。为什么呢?这是因为当源代码变化的时候,Flask开发服务器没有重新载入。只有当你打开程序的调试Debug模式时,才会自动重载。那么让我们修改一下:

app=Flask(__name__)
app.debug=True

现在回到程序运行的终端,按下Ctrl+C组合键来重启服务器(译:windows下,ctrl+c只是停止服务器,需要重新输入命令才能启动。不知道ubuntu下是什么情况)。你将看到当服务器运行之后,在URL旁边会出现一些新的信息输出——类似于“restarting with stat”。这说明一旦代码变更,服务器将自动重新加载之。这很棒,但你发现我们刚才犯下了罪行吗:在处理响应的函数中直接定义了输出模板?小心哟,MVC之神正在盯着你(译:MVC模式要求将视图,模型数据,控制器三者分离)。让我们把视图从控制器中分离开吧。在项目文件夹中创建一个名为templates的文件夹,并在其中新建index.html文件。index.html文件内容如下:

<html>
<head><title>Hi there!</title></head>
<body>
    Hello world!
</body>
</html>

现在更改你的main.py代码如下:

#coding:utf-8
from flask import Flask,render_template

@app.route("/")
def hello():
    return render_template("index.html")

你明白我们做了什么吗?render_template的功能就是从templates/文件夹(Flask的默认模板文件夹)中加载模板,你可以返回输出来渲染它。
现在让我们添加一些JavaScript和CSS样式。默认情况下,Flask内建的开发服务器会从你的项目文件夹下的static子文件夹中搜索。我们创建并添加文件到其中,你的项目文件夹层次应该如下所示:

project/
  --main.py
  --templates/
  ----index.html
  --static/
  ----js
  ------jquery.min.js
  ------foundation.min.js
  ------modernizr.js
  ----css
  ------styles.css
  ------foundation.min.css 

注意,我从foundation.zurb框架(一个很好的css框架你可以从http://foundation.zurb.com/获得)中添加了文件。我建议你也这么做,可以轻松获得一个现代化的,漂亮的站点。你模板中的静态文件路径应该看其来如下:
<script src='/statc/js/modernizr.js'></script>

这个文件夹/static前面的真实路径默认是Flask在调试模式下调用。如果是实际生产模式下,你就必须使用独立的http服务器来提供静态文件。你可以查看本章最后的附加完整代码。

试着使用更好的CSS样式来改进hello world例子。

总计

设置开发服务器是一个非常重要的任务,我们完成了。创建“Hello World”程序是介绍一项新技术最好的办法,我们也完成了。最后我们学到了如何生成HTML页面并使用静态文件,基本上就是大部分web程序做的。在本章你学到了所有技术,我希望这个过程很轻松并且让你满意。
在下章中,我们添加一点挑战性的调味汁,设置更高级的模板。我们将学习如何使用Jinja2包来创建更棒的模板,并允许我们用最少的输入做的更多。
再会吧!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容