Python学习笔记 web开发

来源:互联网 发布:化妆品成分知多少 编辑:程序博客网 时间:2024/05/02 01:00
十九:web 开发
                    一个web应用的本质就是:
                        1:浏览器发送一个http请求:
                        2:服务器收到请求,生成一个HTML文档
                        3:服务器把HTML文档作为http响应的body发送给浏览器
                        4:浏览器收到http响应 从http body取出HTML文档并显示
                    所以 最简单的web应用就是先把HTML用文件保存好,用一个现成的http服务器软件,接受用户请求 从文件中读取HTML 返回 apache nginx lighttpd 
                    我们用Python专注于生成HTML文档 不希望接触TCP链接 http原始请求和响应格式 所以需要一个统一的接口 这个接口就是 WSGI:Web Server Gateway Interface
                    WSGI 接口定义非常简单 他只要求web开发者实现一个函数 就可以相应http请求:
                        def application(environ,start_response):
                            start_response('200 OK',[('Content-Type','text/html')])
                            return '<h1>Hello Web!</h1>'
                    上面的Application()函数就是符合WSGI标准的一个HTTP处理函数 他接受两个参数:
                        1:environ 一个包含所有http请求信息的dict对象
                        2:start_response 一个发送http响应的函数
                    在application()函数中 调用 start_response('200 OK',[('Content-Type','text/html')])就发送了http响应的header 注意header只能发送一次 也就是只能调用一次start_response()函数,它接受两个参数,一个是http响应码,一个是一组list表示http的header 每个header用一个包含两个str的tuple表示
                    通常情况下 都应该把Content-Type 头发送给浏览器 其他很多常用的http header也应该发送
                    然后函数返回值    return '<h1>Hello Web!</h1>' 将作为http响应的body发送给浏览器
                    有了WSGI 我们关心的就是如何从environ 这个dict对象拿到http请求信息 然后构造HTML 通过start_response()函数发送header 最后返回body
                    application()函数必须由WSGI服务器来调用 有很多符合WSGI规范的服务器 Python内置的一个WSGI服务器就是模块wsgiref 
                
                    运行WSGI服务 
                    先编写hello.py 实现web应用程序的WSGI处理函数
                        #hello.py
                        def application(environ,start_response):
                            start_response('200 OK',[('Content-Type','text/html')])
                            return '<h1>hello,web</h1>'
                    然后在编写一个server.py 负责启动WSGI服务器 加载application()函数
                        #server.py
                        #从wsgiref模块导入
                        from wsgiref.simple_server import make_server
                        #导入我们自己编写的application函数
                        from hello import application

                        #创建一个服务器 IP地址为空 端口为8000 处理函数application
                        httpd=make_server('',8000,application)
                        print "serving http on port 8000"
                        #开始监听http请求
                        httpd.serve_forever()
                    确保以上两个文件在同一个目录下 然后在命令行输入 python server.py  来启动WSGI服务器 启动成功后 打开浏览器输入http://localhost:8000/就可以了

                2:使用web框架
                    了解了WSGI框架 我们发现 其实一个web app 就是写一个WSGI的处理函数 针对每个http请求进行相应,但是如何处理http请求不是问题 问题是如何处理100个不同的URL
                    一个最简单的想法是从environ变量中取出http请求的信息然后逐个判断
                        def applicatioin(environ,start_response):
                            method=environ('REQUEST_METHOD')
                            path=environ('PATH_INFO')
                            if method=='GET' and path=='/'
                                return handle_home(environ,start_response)
                            if method=='POST' and path=='/signin'
                                return handle_signin(environ,start_response)
                    这样下去肯定是没有办法维护的 我们需要进一步抽象 让我们专注于用一个函数处理一个URL 至于URL到函数的映射 就交给web框架来做
                    由于用Python开发一个web框架很容易 所以Python有上百个开源的web框架 这里使用flask框架
                    用flask框架编写web app 比WSGI接口简单 我们先用easy_install 或者pip 安装Flask
                        $easy_install flask
                    然后写一个app.py 处理三个URL 分别是
                        1:GET / :首页 返回Home;
                        2: GET /signin : 登陆页 显示登录表单
                        3:POST /signin: 处理登录表单 显示登录结果
                    flask通过Python的装饰器在内部自动的吧URL和函数关联起来 所以代码应该像这样:
                        from flask import Flask
                        from flask import request
                            
                        app=Flask(__name__)
                        @app.route('/',methods=['GET','POST'])
                        def home():
                            return '<h1>Home</h1>'

                        @app.route('/signin',methods=['GET'])
                        def signin_form():
                            return '''<form action="/signin" method="post">
                                            <p><input name="username"></p>
                                            <p><input name="password" type="password"></p>
                                            <p><button type="submit">Sign in</button></p>
                                            </form>'''
                        
                        @app.route('/signin',methods=['POST'])
                        def signin():
                            #需要从request对象读取表单内容
                            if request.form['username']=='admin' and request.form['password']=='password':
                                return '<h3>Hello,admin</h3>'
                            else:
                                return '<h3>Bad username or password </h3>'
        
                        if __name__=='__main__':
                            app.run()                    
                    
                    除了flask外 常见的 web框架还有  Django :全能型web框架  web.py 一个小巧的web框架 Bottle:和flask类似的web框架 tornado Facebook的开源异步框架

                3:使用模板
                    web框架把我们从WSGI中拯救出来了 现在哦我们只需要不断地 编写函数带上URL就可以继续web app 的开发 但是web app 不仅仅是处理逻辑 展示给用户的页面也非常的重要 在函数中返回一个字符串 基本是做不到的,也因此模板技术出现了 使用模板 我们需要预先准备一个HTML文档 这个HTML文档不是普通的HTML文档 而是嵌入了一些变量和指令 然后,根据我们传入的数据,替换后,得到最终的HTML 发送给用户。这就是传说中的MVC 
                    Python处理URL的函数就是C :controller  controller负责业务逻辑 
                    
                    from flask import Flask ,request ,render_template
                    app=Flask(__name__)
        
                    @app.route('/',methods=['GET','POST'])
                    def home():
                        return render_template('home.html')
                    
                    @app.route('/signin',methods=['GET'])
                    def signin_form():
                        return render_template('form.html')
            
                    @app.route('/signin',methods=['POST'])
                    def signin():
                        username=request.form['username']
                        password=request.form['password']
                        if username=='admin' and password=='admin':
                            return render_template('signin-ok.html',username=username)
                        return render_template('form.html',message='Bad username or password')
                
                    if __name__=='__main__':
                        app.run()
                    
                    python  Flask 通过render_template() 函数来实现模板的渲染 和web框架类似 Python的 模板也有很多种 Flask默认支持的模板是 jinja2 所以需要先安装jinja2
                        $ easy_install jinja2

                    然后编写模板 也就是HTML页面例如:form.html
<html>
<head>
 <title>Please Sign In</title>

</head>
<body>
 {% if message %}
 <p style="color:red">{{message}}</p>
 {% endif %}
 <form action="/signin" method="post">
  <legend>Please sign in :</legend>
  <p><input name="username" placeholder="Username" value="{{username}}"></p>
  <p><input name="password" placeholder="Password" type="password"></p>
  <p><button type="submit">Sign in </button></p>
 </form>
</body>
</html>
.                    
                    通过mvc我们在Python代码中处理M 和C 而V通过模板处理 这样我们成功的把Python代码和HTML代码最大限度的分离了
                    使用模板的另一个好处是 模板改起来很方便 而且改完保存后 刷新浏览器就能看到最新的效果
                    在jinja2模板中 我们用{{name}}表示一个需要替换的变量 很多时候循环 条件判断等指令 在jinja2 中 用{% %}表示
                    比如循环输出页码
                        {%for i in page_list %}
                            <a href='/page/{{i}}'>{{i}}</a>
                        {% endfor %}
                    如果page是一个list [1,2,3,4,5] 上面的模板就会输出5个超链接
                    除了jinja2 常见的模板还有:
                        mako:用<%....%> ${xxx}
                        cheetah:同上
                        Django:{%  ... %}   {{xxx}}

0 0
原创粉丝点击