Flask基础学习-配置篇

实例化flask对象:
1
2
3
app = Flask(__name__)

:param import_name: the name of the application package

实例化Flask对象的时候,我们传入参数__name__,该参数作为Flask核心对象的标识(可以是任意字符串),这里传入的是文件目录。

唯一 URL / 重定向行为

我们先看下什么是重定向。

image-20180801211823253

当我们从浏览器请求服务器上的一个资源url1的时候,当资源不存在的时候将会在返回的请求头里面增加一个location: url2,返回的状态码标识为302。当浏览器接收到这样的返回结果后,将重新请求链接url2,这样就能访问到最终的资源。

Flask 的 URL 规则基于 Werkzeug 的路由模块。这个模块背后的思想是基于 Apache 以及更早的 HTTP 服务器主张的先例,保证优雅且唯一的 URL。

1
2
3
4
5
6
7
8
9
10
from flask import Flask

app = Flask(__name__)


@app.route('/hello/')
def hello():
return "hello world"

app.run(debug=True)

image-20180801213005518

当我们直接访问http://127.0.0.1:5000/hello/会直接返回页面,而访问http://127.0.0.1:5000/hello会进行url重定向。

之所以这么设定是为了保证URL的唯一性,防止映射过多,SEO优化繁琐。

上面的情况只有在我们配置URL的时候后面有斜线才能实现,当我们配置URL的时候没有斜线而访问的时候带了斜线,就会报错。

路由注册的另一种方式

除了使用route装饰器进行路由配置之外,我们还可以使用

1
2
3
4
5
6
7
8
9
10
11
12
13
from flask import Flask

app = Flask(__name__)


# @app.route('/hello')
def hello():
return "hello world"


app.add_url_rule('/hello', view_func=hello)

app.run(debug=True)

一般在使用基于类的视图的时候使用add_url_rule,对于route我们看下源码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def route(self, rule, **options):
"""A decorator that is used to register a view function for a
given URL rule. This does the same thing as :meth:`add_url_rule`
but is intended for decorator usage::

@app.route('/')
def index():
return 'Hello World'

For more information refer to :ref:`url-route-registrations`.

:param rule: the URL rule as string
:param endpoint: the endpoint for the registered URL rule. Flask
itself assumes the name of the view function as
endpoint
:param options: the options to be forwarded to the underlying
:class:`~werkzeug.routing.Rule` object. A change
to Werkzeug is handling of method options. methods
is a list of methods this rule should be limited
to (`GET`, `POST` etc.). By default a rule
just listens for `GET` (and implicitly `HEAD`).
Starting with Flask 0.6, `OPTIONS` is implicitly
added and handled by the standard request handling.
"""
def decorator(f):
endpoint = options.pop('endpoint', None)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator

我们从源码中看到装饰器route内部也是使用了add_url_rule,装饰器简化了我们的路由注册。

flask的配置文件

一般我们做项目需要的配置很多,有时有需要分几个文件,如何导入配置文件呢?

我们可以使用from_object进行导入

1
app.config.from_object()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def from_object(self, obj):
"""Updates the values from the given object. An object can be of one
of the following two types:

- a string: in this case the object with that name will be imported
- an actual object reference: that object is used directly

Objects are usually either modules or classes. :meth:`from_object`
loads only the uppercase attributes of the module/class. A ``dict``
object will not work with :meth:`from_object` because the keys of a
``dict`` are not attributes of the ``dict`` class.

"""
if isinstance(obj, string_types):
obj = import_string(obj)
for key in dir(obj):
if key.isupper():
self[key] = getattr(obj, key)

上面是from_object的源码,接收的参数是模块路径名字或者类名。

配置参数一般都是大写,如果是文件直接在文件中进行抒写,如果是类则将配置参数作为类属性。

注意:如果传入的是模块路径名字而不是文件名字

我们将配置文件加载后如何获取呢?

1
app.config['DEBUG']

我们可以通过上面的方式访问我们的配置。

我们看到上面的访问很类似字典的访问类型,其实app.config就是字典dict的一个子类。

注意:当我们使用from_object导入配置的时候,当配置文件或类中的配置项不是全部大写,则不会导入到配置中。

响应对象Response
1
2
3
4
5
6
7
8
9
10
11
@app.route('/hello')
def hello():
# status code 200,301
# content-type http headers
# content-type = text/html
# Response
return "<html></html>"


def hello():
return "hello world"

相比于普通函数,我们的视图函数返回的东西会包含状态类,返回数据类型。

当我们在视图函数中返回一个简单的字符串的时候,flask会把字符串当做响应的主题内容以及其他的刚才提到的状态码数据类型封装到Response对象中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@app.route('/hello')
def hello():
# status code 200,301
# content-type http headers
# content-type = text/html 默认
# Response
# return "hello world"

headers = {
'content-type': 'text/plain'
}

response = make_response('<html></html>', 200)

response.headers = headers

return response

image-20180801223031819

我们使用make_response生成了Response对象,并将数据格式进行了修改。

如果我们想返回字符串格式,只需要将content-type修改为application/json类型。

web数据返回的本质都是字符串,具体返回数据格式都是有content-type来控制如何向客户端解释返回的内容。

对于数据返回我们还可以使用下面的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@app.route('/hello')
def hello():
# status code 200,301
# content-type http headers
# content-type = text/html 默认
# Response
# return "hello world"

headers = {
'content-type': 'text/plain'
}

# response = make_response('<html></html>', 200)
#
# response.headers = headers
#
# return response

return '<html></html>', 200, headers

上面返回的是元组,最终也会生成response对象,并将元组解包传入到对应参数。

知识就是财富
如果您觉得文章对您有帮助, 欢迎请我喝杯水!