博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flask之旅: 快速上手
阅读量:6291 次
发布时间:2019-06-22

本文共 7706 字,大约阅读时间需要 25 分钟。

路由

Flask只有route()装饰器把视图函数绑定到url上面。

@app.route('/user')def hello_user():    return 'Hello, user!'复制代码

另外我们也可以指定动态url。

通过把 URL 的一部分标记为 <variable_name> 就可以在 URL 中添加变量。标记的 部分会作为关键字参数传递给函数。

# 比如获取一个用户详情的url@app.route('/user/
/')def hello_user(id): return 'Hello, userid: {0}!'.format(id)复制代码

<variable_name>默认是字符串, 如果我们需要指定参数类型可以通过:

复制代码

Flask执行的转换器类型:

唯一Url

Flask的URL规则基于Werkzeug的路由模块, 主张保证优雅且唯一的URL。

以上述的例子为例如果你访问

http://0.0.0.0:9999/user/2复制代码

我们定义的路由是'/user//', 如果访问一个结尾不带/的URL会被重定向到带斜杠的URL上去,这样可以保持 URL 唯一,并帮助 搜索引擎避免重复索引同一页面。

构造URL

使用url_for()构建url, 它接受函数名字作为第一个参数, 也接受对应URL规则的变量部分的命名参数, 未知的变量部分会添加到URL末尾作为查询参数。

from flask import Flask, url_forapp = Flask(__name__)app.config['DEBUG'] = True@app.route('/user/
')def user(id): pass# test_request_context() 告诉 Flask 正在处理一个请求with app.test_request_context(): print(url_for('user', id=2)) print(url_for('user', id=3, type='doctor'))if __name__ == '__main__': app.run(host='0.0.0.0', port='9999')复制代码

输出:

/user/2/user/3?type=doctor复制代码

为什么不在把 URL 写死在模板中,而要使用反转函数 url_for() 动态构建?

1. 反转通常比硬编码URL的描述性更好。2. 未来更过URL, 你可以只在一个地方改变 URL,而不用到处替换。3. URL创建会为你处理特殊字符的转义和Unicode数据,比较直观。4. 生产的路径总是绝对路径,可以避免相对路径产生副作用。5. 如果你的应用是放在URL根路径之外的地方(如在 /myapplication 中,不在 / 中), url_for() 会为你妥善处理。复制代码

跳转与重定向

跳转(301)多用于旧网址在废弃之前转向新网址保证用户的访问, 有页面被永久性易走的概念。

重定向(302)表示页面只是暂时的转移, 不建议经常性使用重定向。

redirect(location) #默认是302redirect(location, code=301) # 可以指定code复制代码
from flask import Flask, url_for, render_template, redirectapp = Flask(__name__)app.config['DEBUG'] = True@app.route('/')def index():    return redirect(url_for('login'))@app.route('/login')def login():    return render_template('login.html')if __name__ == '__main__':    app.run(host='0.0.0.0', port='9999')    复制代码

HTTP方法

Web 应用使用不同的 HTTP 方法处理 URL,默认情况下,一个路由只回应 GET 请求。可以使用 route() 装饰器的 methods 参数来处理不同的 HTTP 方法:

@app.route('/login', methods=['GET', 'POST'])复制代码

简单介绍下常见的HTTP方法与使用场景:

- GET: 获取资源, GET操作应该是幂等的- HEAD: 想要获取信息, 但是只关心消息头, 应该可以把它当作GET来处理, 但是不返回内容。具有幂等性- POST: 创建一个资源, 非幂等方法- PUT: 完整的替换资源或者创建资源, 是幂等方法- DELETE: 删除资源, 是幂等方法- OPTIONS:获取资源所支持的所有HTTP方法- PATCH: 局部更新, 非幂等方法复制代码

HTTP幂等方法,是指无论调用多少次都不会有不同结果的 HTTP 方法。不管你调用一次,还是调用一百次,一千次,结果都是相同的。

关于。

在视图函数里面我们可以使用如下方式判断HTTP请求方法

from flask import Flask, requestrequest.method # 获取当前请求的方法复制代码

静态文件

动态的 web 应用也需要静态文件,一般是 CSS 和 JavaScript 文件。理想情况下你的 服务器已经配置好了为你的提供静态文件的服务。但是在开发过程中, Flask 也能做好 这项工作。只要在你的包或模块旁边创建一个名为 static 的文件夹就行了。 静态文件位于应用的 /static 中。

在实例化Flask时候如果你查看源码你会发现app = Flask(__name__)def __init__(        self,        import_name,        static_url_path=None,        static_folder='static',        static_host=None,        host_matching=False,        subdomain_matching=False,        template_folder='templates',        instance_path=None,        instance_relative_config=False,        root_path=None    ):复制代码

static为默认的静态文件的目录。

# 这样是可以直接访问到静态文件的http://0.0.0.0:9999/static/app.css复制代码

我们不建议在模板里面直接写死静态文件路径, 应该使用url_for()生成路径

url_for('static', filename='app.css')复制代码

当然我们也可以定制静态文件的真实目录

app = Flask(__name__, static_folder='/tmp')复制代码

渲染模板

Flask默认提供的是Jinja2 模板引擎。

使用 render_template() 方法可以渲染模板,你只要提供模板名称和需要 作为参数传递给模板的变量就行了。下面是一个简单的模板渲染例子:

templates是Flask默认的目录名字。

@app.route('/')def index():    return render_template('index.html', title='首页')复制代码
    
{<div></div> {title}}复制代码

在模板内部可以和访问 get_flashed_messages() 函数一样访问 request 、 session 和 g对象[g保存的是当前请求的全局变量,不同的请求会有不同的全局变量]。

这里就不细说了, 后面有空单独写一篇, 现在前后分离, 已经比较少使用模板了。

操作request对象

在Flask 中由全局对象request来提供请求信息。如果你有一些 Python 基础,那么 可能 会奇怪:既然这个对象是全局的,怎么还能保持线程安全?

from flask import request复制代码

某些对象在 Flask 中是全局对象,但不是通常意义下的全局对象。这些对象实际上是 特定环境下本地对象的代理。真拗口!但还是很容易理解的。

从一个 Flask App 读入配置并启动开始,就进入了 App Context,在其中我们可以访问配置文件、打开资源文件、通过路由规则反向构造 URL。当一个请求进入开始被处理时,就进入了 Request Context,在其中我们可以访问请求携带的信息,比如 HTTP Method、表单域等。

request虽然是全局变量但是只是一个代理, 想深挖细节的可以看看这个文章。

- 通过使用 method 属性可以操作当前请求方法- 通过使用 form 属性处理表单数据(在 POST 或者 PUT 请求 中传输的数据), 当 form 属性中不存在这个键时会发生什么?会引发一个 KeyError 。 如果你不像捕捉一个标准错误一样捕捉 KeyError ,那么会显示一个 HTTP 400 Bad Request 错误页面。- 要操作 URL (如 ?key=value )中提交的参数可以使用 args 属性:searchword = request.args.get('key', '')复制代码

响应

视图函数的返回值会被转为一个响应对象。

比如:

# 你会发现页面里面没有文字显示, 只有h3标签@app.route('/')def index():    return '

'复制代码

你查看app.route()源码会发现

# route装饰器只是一个语法糖, 实际执行的还是add_url_rule()def decorator(f):    endpoint = options.pop('endpoint', None)    self.add_url_rule(rule, endpoint, f, **options)    return freturn decorator复制代码

转化逻辑如下:

1. 如果返回的是一个合法的响应对象, 它会从视图直接返回2. 如果返回的是一个字符串, 会用字符串数据和默认参数来创建以字符串为主体, 状态码为200,MIME类型的text.html的werkzeug.wrappers.Response响应对象。3. 如果返回的是一个元组, 且元组的元素可以提供额外的信息, 这样的元组格式为(response, status, headers)。它们会覆盖默认的配置。4. 如果上述条件都不对, Flask会假设返回值是一个合法的WSGI应用程序, 并通过Response.force_type(rv, request.environ)转化为请求对象复制代码

实例:

@app.route('/')def index():    return render_template('index.html'), 400复制代码

我们也可以显示使用make_response方法

from flask import Flask, url_for, render_template, redirect, request, make_responseapp = Flask(__name__)app.config['DEBUG'] = True@app.route('/')def index():    response = make_response(render_template('index.html'), 400)    return response复制代码

使用make_response方法我们可以设置cookie, 头信息等。

查看make_response方法源码其实也很好理解。

def make_response(*args):    # 根据args传参情况进行不同处理    if not args:        return current_app.response_class()    if len(args) == 1:        args = args[0]    return current_app.make_response(args)复制代码
def make_response(self, rv):    status = headers = None    # unpack tuple returns    # 传入的是元组    if isinstance(rv, tuple):        len_rv = len(rv)        # 格式(response, status, headers)        if len_rv == 3:            rv, status, headers = rv        # decide if a 2-tuple has status or headers        elif len_rv == 2:            if isinstance(rv[1], (Headers, dict, tuple, list)):                rv, headers = rv            else:                rv, status = rv        # other sized tuples are not allowed        else:            raise TypeError(                'The view function did not return a valid response tuple.'                ' The tuple must have the form (body, status, headers),'                ' (body, status), or (body, headers).'            )    # the body must not be None    if rv is None:        raise TypeError(            'The view function did not return a valid response. The'            ' function either returned None or ended without a return'            ' statement.'        )    # make sure the body is an instance of the response class    if not isinstance(rv, self.response_class):        if isinstance(rv, (text_type, bytes, bytearray)):            # let the response class set the status and headers instead of            # waiting to do it manually, so that the class can handle any            # special logic            rv = self.response_class(rv, status=status, headers=headers)            status = headers = None        else:            # evaluate a WSGI callable, or coerce a different response            # class to the correct type            try:                rv = self.response_class.force_type(rv, request.environ)            except TypeError as e:                new_error = TypeError(                    '{e}\nThe view function did not return a valid'                    ' response. The return type must be a string, tuple,'                    ' Response instance, or WSGI callable, but it was a'                    ' {rv.__class__.__name__}.'.format(e=e, rv=rv)                )                reraise(TypeError, new_error, sys.exc_info()[2])    # prefer the status if it was provided    if status is not None:        if isinstance(status, (text_type, bytes, bytearray)):            rv.status = status        else:            rv.status_code = status    # extend existing headers with provided headers    if headers:        rv.headers.extend(headers)    return rv复制代码

转载地址:http://mtcta.baihongyu.com/

你可能感兴趣的文章
springmvc Could not write content: No serializer
查看>>
Python系语言发展综述
查看>>
新手 开博
查看>>
借助开源工具高效完成Java应用的运行分析
查看>>
163 yum
查看>>
第三章:Shiro的配置——深入浅出学Shiro细粒度权限开发框架
查看>>
80后创业的经验谈(转,朴实但实用!推荐)
查看>>
让Windows图片查看器和windows资源管理器显示WebP格式
查看>>
我的友情链接
查看>>
vim使用点滴
查看>>
embedded linux学习中几个需要明确的概念
查看>>
mysql常用语法
查看>>
Morris ajax
查看>>
【Docker学习笔记(四)】通过Nginx镜像快速搭建静态网站
查看>>
ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
查看>>
<转>云主机配置OpenStack使用spice的方法
查看>>
java jvm GC 各个区内存参数设置
查看>>
[使用帮助] PHPCMS V9内容模块PC标签调用说明
查看>>
关于FreeBSD的CVSROOT的配置
查看>>
基于RBAC权限管理
查看>>