美文网首页
Python Web开发

Python Web开发

作者: _YZG_ | 来源:发表于2018-01-11 12:41 被阅读46次

    web应用的本质
    1、浏览器发送一个HTTP请求;
    2、服务器收到请求,生成一个HTML文档;
    3、服务器把HTML文档作为HTTP响应的Body发送给浏览器;
    4、浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示。

    WSGI:Web Server Gateway Interface。

    WSGI接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求

    实现Web应用程序的WSGI处理函数,如下

    HTTP请求的所有输入信息都可以通过environ获得,HTTP响应的输出都可以通过start_response()加上函数返回值作为Body。

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    def application(environ, start_response):
        # Header只能发送一次,也就是只能调用一次start_response()函数
        start_response('200 OK', [('Content-Type', 'text/html')])
        body = '<h1>Hello, %s!</h1>' % (environ['PATH_INFO'][1:] or 'web')
        return [body.encode('utf-8')]
    
    

    environ:一个包含所有HTTP请求信息的dict对象;

    start_response:一个发送HTTP响应的函数。

    Python内置了一个WSGI服务器,这个模块叫wsgiref,它是用纯Python编写的WSGI服务器的参考实现。所谓“参考实现”是指该实现完全符合WSGI标准,但是不考虑任何运行效率,仅供开发和测试使用。

    无论多么复杂的Web应用程序,入口都是一个WSGI处理函数。

    负责启动WSGI服务器,加载application()函数:

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    # 从wsgiref模块导入:
    from wsgiref.simple_server import make_server
    
    # 导入我们自己编写的application函数:
    from hello2 import application
    
    # 创建一个服务器,IP地址为空,端口是8000,处理函数是application:
    # 如果8000端口已被其他程序占用,启动将失败,请修改成其他端口
    httpd = make_server('', 8000, application)
    print('Serving HTTP on port 8000...')
    # 开始监听HTTP请求:
    httpd.serve_forever()
    
    

    启动成功后,打开浏览器,输入http://localhost:8000/

    确保以上两个文件在同一个目录下,然后在命令行启动WSGI服务

    使用Web框架Flask

    用Flask编写Web App比WSGI接口简单

    然后写一个app.py,处理3个URL,分别是:

    GET /:首页,返回Home;

    GET /signin:登录页,显示登录表单;

    POST /signin:处理登录表单,显示登录结果。

    注意噢,同一个URL/signin分别有GET和POST两种请求,映射到两个处理函数中。

    Flask通过Python的装饰器在内部自动地把URL和函数给关联起来

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    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>'
        return '<h3>Bad username or password.</h3>'
    
    if __name__ == '__main__':
        app.run()
    
    

    直接运行,Flask自带的Server在端口5000上监听

    打开浏览器输入http://localhost:5000/
    输入http://localhost:5000/signin
    输入admin和password登录成功,否则登录失败

    除了Flask,常见的Python Web框架还有:

    • Django:全能型Web框架;

    • web.py:一个小巧的Web框架;

    • Bottle:和Flask类似的Web框架;

    • Tornado:Facebook的开源异步Web框架。

    使用模板

    Flask通过render_template()函数来实现模板的渲染
    和Web框架类似,Python的模板也有很多种。Flask默认支持的模板是jinja2

    有了MVC,我们就分离了Python代码和HTML代码。HTML代码全部放到模板里,写起来更有效率

    继续用上面的例子用MVC模式改写

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    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=='password':
            return render_template('signin-ok.html', username=username)
        return render_template('form.html', message='Bad username or password', username=username)
    
    if __name__ == '__main__':
        app.run()
    
    

    编写jinja2模板
    home.html

    <html>
    <head>
      <title>Home</title>
    </head>
    <body>
      <h1 style="font-style:italic">Home</h1>
    </body>
    </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>
    
    

    signin-ok.html 登录成功的模板

    <html>
    <head>
      <title>Welcome, {{ username }}</title>
    </head>
    <body>
      <p>Welcome, {{ username }}!</p>
    </body>
    </html>
    
    

    登录失败的模板在form.html中加了一条判断,把form.html重用为登录失败的模板

    把模板放到正确的templates目录下,templatesapp.py在同级目录下

    启动python app.py

    在Jinja2模板中,我们用{{ name }}表示一个需要替换的变量。很多时候,还需要循环、条件判断等指令语句,在Jinja2中,用{% ... %}表示指令。

    比如循环输出页码:

    {% for i in page_list %}
        <a href="/page/{{ i }}">{{ i }}</a>
    {% endfor %}
    

    如果page_list是一个list:[1, 2, 3, 4, 5],上面的模板将输出5个超链接。

    除了Jinja2,常见的模板还有:

    • Mako:用<% ... %>${xxx}的一个模板;

    • Cheetah:也是用<% ... %>${xxx}的一个模板;

    • Django:Django是一站式框架,内置一个用{% ... %}{{ xxx }}的模板。

    相关文章

      网友评论

          本文标题:Python Web开发

          本文链接:https://www.haomeiwen.com/subject/ykvnnxtx.html