笨方法学Python习题50—你的第一个网站

你的第一个网站

这个习题及后面的习题中,你的任务是将前面创建的游戏做成网页版。难度相当大,你要费些时间才能做出来。开始这个习题前,你必须已经成功完成习题46的内容,正确安装了pip, 而且学会了如何安装软件包以及创建项目骨架目录。

安装lpthw.web

创建你的第一个web应用程序之前,你需要安装一个“web框架”,它的名字叫lpthw.web。所谓的“框架”通常指“让某件事情做起来更容易的软件包”。在web应用程序的世界里,人们创建了各种各样的“web框架”,用来解决他们在搭建网站时遇到的各种问题,然后把这些解决方案用软件包的方式发布出来,这样你就可以下载这些软件包,用他们引导你自己的项目了。

可选的框架很多,我们在这使用lpthw.web框架。你可以先学会它,等到差不多的时候再去接触其他框架。lpthw.web本身挺不错的,就算你一直使用也没关系

使用pip安装lpthw.web:
$ sudo pip install lpthw.web
[sudo] passward for zedshaw:
Downloading/unpacking lpthw.web
    Running setup.py egg.info for package lpthw.web
Installing collected packages:lpthw.web
    Running setup.py install for lpthw.web
Successfully installed lpthw.web
Cleaning up...
上面是Linux和Mac OSX系统下的安装命令,Windows把前边的sudo去掉就可以了。若无法正常安装,回习题46,确认自己学会了。

注意   其他程序员会警告你lpthw.web只是另外一个叫web.py的web框架的代码fork,而web.py里面又包含了太多的“魔法”,若他们这么说,你告诉他们Google App Engine 最早是用的就是web.py, 但是没有一个程序员抱怨过它里边包含了太多的“魔法”,因为Google用它也没啥问题。

写一个简单的“Hello World”项目

现在做一个非常简单的“Hello World”项目出来。首先你要创建一个项目目录:
$ cd projects
$ mkdir gothonweb
$ cd gothonweb
$ mkdir bin gothonweb tests docs templates
$ touch gothonweb/__init__.py
$ touch tests/__init__.py

最终目的是把习题42中的游戏做成一个web应用程序,所以你项目名称叫做gothonweb。在此之前,你需要创建一个最基本的lpthw.web应用程序,将下列代码放到bin/app.py中。
import web
urls = (
    '/', 'index'
)
app = web.application(urls, globals())
class index:
    def GET(self):
        greeting = "Hello World"
        return greeting
if __name__ == "__main__":
    app.run()

然后使用下面的方法来运行这个web应用程序:
$ python bin/app.py
http://0.0.0.0:8080/
不过你执行下面的命令你就错了:
$ cd bin/             # WRONG! WRONG! WRONG!
$ python app.py # WRONG! WRONG! WRONG!

在所有的Python项目中,你都不需要进到底层目录去运行东西。你应该待在最上层目录运行,这样才能保证所有模块和文件都能被正常访问到。详情请看习题46关于项目布局的知识。

最后,使用你的web浏览器打开http://localhost:8080/,你应该看到两样东西,首先是浏览器里显示了Hello, World!,然后是你的命令行终端显示了如下输出:
$ python bin/app.py
http://0.0.0.0:8080/
127.0.0.1:59542 - - [13/Jun/2011 11:44:43] "http/1.1 GET /" - 200 OK
127.0.0.1:59542 - - [13/Jun/2011 11:44:43] "http/1.1 GET /favicon.ico" - 404 Not Found
这些是lpthw.web打印出的日志(log)信息,从这些信息可看出服务器在运行,且能了解到程序在浏览器背后做了什么事情。这些信息还有助于你发现程序的问题。如,在最后一行它告诉你浏览器试图获取/favicon.ico,但是这个文件不存在——返回状态码是 404 Not Found. 

以上没有讲到任何web相关的工作原理,因为首先你需要完成准备工作,以便后面的学习能顺利进行,下边两个习题会有详细解释。会要求你用各种方法把你的lpthw.web应用程序弄 坏,然后再将其重新构建起来——让你明白运行lpthw.web程序需要准备好哪些东西。

会发生什么

在浏览器访问你的web应用程序时,发生如下事情:

1. 浏览器通过网络连接到你的电脑,它的名字叫做localhost,这是一个标准称谓,表示的就是网络中你的这台计算机,不管它实际名字是什么,你都可以使用localhost来访问。它使用的端口是8080.
2. 连接成功后,浏览器对bin/app.py这个应用程序发出了HTTP请求(request),要求访问URL/, 这通常是一个网站的第一个URL。
3. 在bin/app.py里,有一个列表,里边包含了URL和类的匹配关系。这里只定义了一组匹配,那就是'/', 'index'的匹配。它的含义是:如果有人使用浏览器访问/这一级目录,lpthw.web将找到并加载class index, 从而用它处理这个浏览器的请求。
4. 现在lpthw.web找到了class index, 然后针对这个类的一个实例调用了index.GET这个方法。该函数运行后返回了一个字符串,以供lpthw.web将其传递给浏览器。

5. 最后,lpthw.web完成了对于浏览器请求的处理,将响应(response)回传给浏览器,于是你就看到了现在的页面。

确定你弄懂了以上,你可能需要画一个示意图,来理清信息是如何从浏览器传递到lpthw.web,再到index.GET,再回到你的浏览器的。

修正错误

第一步,将11行的greeting变量赋值删掉,然后刷新浏览器。你应该会看到一个错误页面,你可以通过这一页丰富的错误信息看出你的程序崩溃的原因是什么。当然你已经知道出错的原因是greeting的赋值丢失了,但lpthw.web还是会给你一个挺好的错误页面,让你能找到出错的具体位置。试试在这个错误页面上做以下操作。

1. 检查每一段local vars 输出(用鼠标点击它们), 追踪里边提到的变量名称,以及它们是在哪些代码文件中用到的。

2. 阅读 Request Information 一节,看看里边哪些知识是你已经熟悉了的,请求是浏览器发给你的gothonweb应用程序的信息。这些知识对于日常web浏览器没有什么用处,但现在你要学会这些,以便写出web应用程序来

3. 试着把这个小程序的别的位置改错,探索一下会发生什么事情。lpthw.web会把一些错误信息和栈跟踪(stack trace)信息显示在终端上, 所以别忘记检查终端的信息输出。

创建基本的模板文件

你有没有注意到“Hello World”并不是一个好HTML网页呢?这是一个web应用程序,所以需要一个合适的HTML响应页面才对。为达到这个目的,下一步你需要将“Hello World”以较大的绿色字体显示出来。

第一步是创建一个templates/index.html文件:
$def with (greeting)
    
        
            Gothons of Planet Percal  #25
        
    
    $if greeting:
    I just wanted to say $greeting
.
    $else:
        Hello, world!
   
   

如果你学过HTML, 这些内容看上去应该很熟悉,如果没有学过,你应该去研究一下,试着用HTML写几个网页,以便了解它的工作原理。但我们这里的HTML文件其实是一个“模板”(template),如果你向模板提供一些参数,lpthw.web就会在模板中找到对应的位置,将参数的内容填充到模板中。如出现$greeting的位置都是传递给模板的变量,这些变量会改变模板显示的内容。

为了让bin/app.py处理模板,需要写一写代码,告诉lpthw.web去哪里找到模板进行加载,以及如何渲染(render)这个模板,按下面方式修改你的app.py

import web

urls = (
    '/', 'Index'

)

app = web.application(urls, globals())

render = web.template.render('templates/')

class Index(object):
    def GET(self):
        greeting = "Hello World"

        return render.index(greeting = greeting)

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

特别注意render这个新变量名,注意我修改了index.GET的最后一行,让它返回了render.index(), 并且将greeting变量作为参数传递给了这个函数。

改好之后,刷新网页,你会看到一条和之前不同的绿色信息输出。你还可在浏览器中通过“查看源文件”看到模板被渲染成了标准有效的HTML源代码。

模板的工作原理:

1. 在bin/app.py 里面添加了一个叫做render的新变量,它本身是一个web.template.render对象。
2. 将templates/作为参数传递给了这个对象,这样就让render知道了从哪里去加载模板文件
3. 在后面的代码中,当浏览器一如既往的触发index.GET后,它没有在返回简单的greeting字符串,取而代之调用了render.index, 而且将问候语句作为一个变量传递给它。
4. 这个render_template函数可以说是一个魔法函数,它看到了你需要的是index.html, 于是就跑到templates/目录下找到名字为index.html的文件,然后就把它渲染一遍
5. 在templates/index.html文件中,可看到初始定义一行中说这个模块需要使用一个叫greeting的参数,这和函数定义中的格式差不多。另外和Python语法一样模板是缩进敏感的,所以要确认自己弄对了缩进。
6. 让templates/index.html 去检查greeting这个变量,如果这个变量存在,就打印出变量的内容;不存在,就打印一个默认的问候信息。

要深入理解这个过程,你可修改greeting变量及HTML模板的内容,看看会有什么效果。然后创建一个叫templates/foo.html的模板,并且使用一个新的render.foo()(而不是像之前使用render.index())去渲染它。从这个过程也可看出,render调用的函数名称只要跟template/下的.html文件名匹配到,这个HTML模板就可以被渲染了。

附加练习

1. 到http://webpy.org/阅读里边的文档,它其实和lpthw.web是同一个项目

2. 实验一下你在上述网站上看到的所有内容,包括里边的代码实例

3. 阅读一下与HTML5和CSS3相关的东西,自己练习写几个.html和.css文件

4. 如果有懂Django朋友帮你,你可以试着使用Django完成一下习题50、习题51和习题52,看看结果会是什么样子。

常见问题回答

我没法连接到http://localhost:8080/?

那就试试http://127.0.0.1:8080/

lpthw.web和web.py有什么不同?

一样,是web.py的某个版本

我找不到index.html(或别的文件)?

很可能你先跑了cd bin/然后才开始做项目的。不要这样做,所有指令都应在bin/的上一层目录中完成,所以如果你无法运行python bin/app.py,就说明你不在正确的目录下

为什么调用模板时要写greeting=greeting?

这一句并不是赋值给greeting,而是将一个命名参数传到模板中。这也算是一种赋值,不过只会在模板函数的调用中生效。

我计算机的端口8080无法使用?

也许是哪个杀毒软件占用了这个端口,换一个就好了

安装lpthw.web时出现ImportError "No module named web"?

很可能是你在系统中安装了多个版本的python,而在这里你用来错误的一个,或者由于pip版本太旧导致安装没有正确完成。试着卸载并重装lpthw.web。如果不行,那在仔细检查一下,确认自己安装了正确的版本。

你可能感兴趣的:(笨方法学Python习题50—你的第一个网站)