[贰]Flask web开发:程序的基本结构

熵流
• 阅读 3734

本系列笔记是我阅读Miguel Grinberg的《Flask Web Development》的笔记,标题与书本同步。希望通过记录技术笔记的方式促进自己对知识的理解。

本篇对应书本第二章:程序的基本结构。

初始化

from flask import Flask #导入Flask模块
app = Flask(__name__) #创建Flask类的实例

注:对于Flask开发者来说,传给Flask应用程序构造函数的name参数是比较容易弄混淆的。Flask使用这个参数来确定应用程序的根目录,这样以后可以相对这个路径来找到资源文件。

路由和视图函数

注册新的路由

在Flask应用中,路由是指用户请求的URL与视图函数之间的映射。
Flask框架 根据HTTP请求的URL在路由表中匹配预定义的URL规则,找到对应的视图函数, 并将视图函数的执行结果返回WSGI服务器。
[贰]Flask web开发:程序的基本结构

匹配动态URL

route装饰器 :可以使用Flask应用实例的route装饰器将一个URL规则绑定到一个视图函数上。
下面程序中route装饰器将根目录绑定在index视图上。

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

URL变量类型过滤


@app.route('/user/<name>')
def user(name):
    return '<h1>Hello, %s</h1>' % name

类似:
int    接受整数(float接受浮点数)
@app.route('/post/<int:post_id>')
path转换器允许规则匹配包含/的字符串。
@app.route('/file/<path:fname>')

启动服务器

if __name__ == '__main__':
    app.run(debug=True)
    
# 模块是对象,并且所有的模块都有一个内置属性 __name__。
# 一个模块的 __name__ 的值取决于您如何应用模块。
# 如果 import 一个模块,那么模块__name__ 的值通常为模块文件名,不带路径或者文件扩展名。
# 但是您也可以像一个标准的程序样直接运行模块,
# 在这种情况下, __name__ 的值将是一个特别缺省"__main__"。

# debug=True 调试模式开启

一个完整的程序

hello.py: 一个完整的Flask程序

from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

if __name__ == '__main__'
    app.run(debug=True)

运行结果如下:
[贰]Flask web开发:程序的基本结构

hello.py: 包含动态路由的Flask程序

from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'
    
@app.route('/user/<name>')
def user(name):
    return '<h1>Hello,%s</h1>' % name
    
if __name__ == '__main__'
    app.run(debug=True)
    
# 定义了动态路由/user/<name>

运行结果如下:
[贰]Flask web开发:程序的基本结构

请求-响应循环

程序和请求上下文

请求对象封装了客户端发送的HTTP请求。
将请求对象作为参数传入视图函数,视图函数即可访问请求对象。

from flask import request

@app.route('/')
def index():
    user_agent = request.headers.get('User-Agent')
    return '<p>Your browser is %s</p>' % user_agent
    

Flask上下文全局变量

变量名 上下文 说明
current_app 程序上下文 当前激活程序的程序实例
g 程序上下文 处理请求时用作临时存储的对象。每次请求都会重设这个变量。
request 请求上下文 请求对象,封装了客户端发出的HTTP请求中的内容。
session 请求上下文 用户会话,用户存储请求之间需要“记住”的值的词典

程序上下文使用方法:

>>> from hello import app
>>> from flask import current_app
>>> current_app.name
Traceback(most recent call last):
...
RuntimeError:working outside of application context
>>> app_ctx = app.app_context()
>>> app_ctx.push()
>>> current_app.name
'hello'
>>> app_ctx.pop()
# app.app_context()可获得一个程序上下文

请求调度

URL映射中的HEAD、Options、GET是请求方法,由路由进行处理。
不同的请求方法发送到相同的URL上时,会使用不同的视图函数进行处理。

请求钩子

Flask支持以下4种钩子:

  • before_first_request:注册一个函数,在处理第一个请求之前运行。

  • before_request:注册一个函数,在每次请求之前运行。

  • after_request:注册一个函数,如果没有未处理的异常抛出,也在每次请求之后运行。

  • teardown_request:注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行。

响应

创建响应对象并设置Cookie

from flask import make_response

@app.route('/'):
def index():
    response = make_response(<h1>This document carries a cookie.</h1>)
    response.set_cookie('answer','42')
    return response

重定向

from flask import redirect

@app.route('/')
def index():
    return redirect('http://www.example.com')

错误处理

from flask import abort

@app.route('/user/<id>')
def get_user(id):
    user = load_user(id)
    if not user:
        abort(404)
    return '<h1>Hello, %s</h1>' % user.name
    

Flask扩展

Flask被设计为可扩展模式,一些重要功能是用安装包的形式增加。

使用Flask-Script支持命令行选项


(venv)$pip install flask-script

hello.py:使用Flask-Script

from flask_script import Manager
manager = Manager(app)
# ...
if __name__ == '__main__':
    manager.run()

运行Python程序: python hello.py runserver
web服务器可使用http://a.b.c.d:5000/ 网络中的任一台电脑进行访问,其中'a.b.c.d'是服务器所在计算机的外网的IP地址。
Python hello.py runserver --host 0.0.0.0


本文由 EverFighting 创作,采用 知识共享署名 3.0 中国大陆许可协议 进行许可。

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
4年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
4年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
4年前
Gson之实例五
前面四篇博客基本上可以满足我们处理的绝大多数需求,但有时项目中对json有特殊的格式规定.比如下面的json串解析:{"tableName":"students","tableData":{"id":1,"name":"李坤","birthDay":"Jun 22, 2012 9:54:49 PM"},{"id":2,"name":"曹贵生"
Wesley13 Wesley13
4年前
Java工程师之Redis实战系列教程前言&目录
系列前言Java工程师之Redis实战系列教程,同其他教程一样,均是在下学习笔记,本系列主要参考自《Redisinaction》,将书本中的有趣的例子转化为能解决特定问题的示例程序,所有的核心章节均提供示例源码在javacourseredisinaction(https://www.oschina.net/action/GoToLi
Stella981 Stella981
4年前
C++笔记002:VS2010报错:LINK fatal error LNK1123 转换到 COFF 期间失败文件无效或损坏
 原创笔记,转载请注明出处!点击【关注】,关注也是一种美德~错误描述:1已启动生成:项目:FirstCode,配置:DebugWin321生成启动时间为2018/2/521:00:30。1InitializeBuildStatus:1 正在
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这