版权声明:原创,如有需要,请标明文章出处,写写合作 https://blog.csdn.net/bingdianerer/article/details/87906700
上节回顾
- 什么是虚拟环境?
- 为什么要安装虚拟环境?
- 你平时都用什么虚拟环境?
- 虚拟环境的安装步骤和使用?
Flask 入门
- 郑重的写下 Hello World ,新建一个 index.py
-*- coding = utf-8 -*-
from flask import Flask
app = Flask(__name__)
@app.route('/hello')
def hello_world():
return 'Hello World'
if __name__ == '__main__':
app.run()
-
启动程序,在浏览器中输入 http://127.0.0.1:5000/hello 就可以熟悉的看到 Hello World.
-
解析这段代码
- 第1行,是声明Python源文件的编码方式,一般只适用于python2的版本,python2版本默认采用的是ASCII,而python3默认的是Unicode。在python3的环境中,这句话是不需要写的。
- 第2行,是在flask模块中引入Flask类文件,也就是Flask框架的核心类。
- 第3行,实例化Flask类,它接收模块或者包作为参数,一般是接收 name, 由这个名字确定项目的根目录,从而确定static目录和templates目录
- 第5~7行,装饰器将url和视图函数绑定一起放在app.url_map中,处理URL和视图函数的关系的程序叫做路由,这里的函数就是 hello_world
- 第9~10行,判断是否实在当前文件启动的,如果是,则执行app.run() 启动flask程序,否则不做任何操作。
-
app.route() 源码解析
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() 方法,那么我们继续追踪 add_url_rule()
def add_url_rule(self, rule, endpoint=None, view_func=None,
provide_automatic_options=None, **options):
"""Connects a URL rule. Works exactly like the :meth:`route`
decorator. If a view_func is provided it will be registered with the
endpoint.
Basically this example::
@app.route('/')
def index():
pass
Is equivalent to the following::
def index():
pass
app.add_url_rule('/', 'index', index)
If the view_func is not provided you will need to connect the endpoint
to a view function like so::
app.view_functions['index'] = index
Internally :meth:`route` invokes :meth:`add_url_rule` so if you want
to customize the behavior via subclassing you only need to change
this method.
For more information refer to :ref:`url-route-registrations`.
.. versionchanged:: 0.2
`view_func` parameter added.
.. versionchanged:: 0.6
``OPTIONS`` is added automatically as method.
: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 view_func: the function to call when serving a request to the
provided endpoint
:param provide_automatic_options: controls whether the ``OPTIONS``
method should be added automatically. This can also be controlled
by setting the ``view_func.provide_automatic_options = False``
before adding the rule.
: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.
"""
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)
options['endpoint'] = endpoint
methods = options.pop('methods', None)
# if the methods are not given and the view_func object knows its
# methods we can use that instead. If neither exists, we go with
# a tuple of only ``GET`` as default.
if methods is None:
methods = getattr(view_func, 'methods', None) or ('GET',)
if isinstance(methods, string_types):
raise TypeError('Allowed methods have to be iterables of strings, '
'for example: @app.route(..., methods=["POST"])')
methods = set(item.upper() for item in methods)
# Methods that should always be added
required_methods = set(getattr(view_func, 'required_methods', ()))
# starting with Flask 0.8 the view_func object can disable and
# force-enable the automatic options handling.
if provide_automatic_options is None:
provide_automatic_options = getattr(view_func,
'provide_automatic_options', None)
if provide_automatic_options is None:
if 'OPTIONS' not in methods:
provide_automatic_options = True
required_methods.add('OPTIONS')
else:
provide_automatic_options = False
# Add the required methods now.
methods |= required_methods
rule = self.url_rule_class(rule, methods=methods, **options)
rule.provide_automatic_options = provide_automatic_options
self.url_map.add(rule)
if view_func is not None:
old_func = self.view_functions.get(endpoint)
if old_func is not None and old_func != view_func:
raise AssertionError('View function mapping is overwriting an '
'existing endpoint function: %s' % endpoint)
self.view_functions[endpoint] = view_func
在 92 行,url_map()将规则加入,形成一个闭环。在我们不需要 app.route(’/hello’)时,也可以使用app.add_url_rule(’/hello’,view_func(‘hello_world’))
-
如果路由规则 app.route(’/hello/’)
- 启动程序后,输入 http://127.0.0.1/hello, 则会报错。
- 如果输入 http://127.0.0.1/hello/, 则正常。
- 请求流程图
-
启动参数
- host: 指定ip地址 一般会写 0.0.0.0
- port: 指定的端口号
- debug: 开启/关闭调试模式
- load_dotenv: 用来加载设置环境变量的文件
可以在根目录文件下创建config.py文件,在入口文件 app.py 里引入
config.py
DEBUG=True
PORT = 8888
HOST = '127.0.0.1'
from flask import Flask
app = Flask(__name__)
app.config.from_object('config.py')
@app.route('/hello')
def hello_world():
return 'Hello World'
if __name__ == '__main__':
app.run(host=app.config['HOST'],port=app.config['PORT'],debug=app.config['DEBUG'])
- 怎么理解if name == ‘main’ 这句话?
- 绝大部分python程序都会有这个语句,确保if里面的语句执行的条件。如果这个文件是 main(主程序)时,这个条件里的程序才会执行。这只是我们利用flask的简易的web服务的时候,也就是平时我们开发时需要的环境。但是在生产环境中,我们一般会采取nginx+uwsgi方式来部署,在生产环境中,这个py文件是被导入执行,所以__name__ 就是导入文件的那个文件名称,如果没有if 判断的话,app.run()会被执行两次,这样会引起flask的冲突。所以加上这个if语句。
- 视图函数和普通函数有什么区别?
- 普通函数返回:可以返回字符串,列表,远祖,字典,以及对象
- 视图函数返回: 返回Response对象,并可能会附加一些其他的信息,比如说状态码(status code),返回类型(content-type),以及其他。