Heim >Backend-Entwicklung >Python-Tutorial >Python-Superstar-WEB-Framework Flask
Einführung in Flask
Flask ist im Vergleich zu Django ein leichtes Web-Framework.
Im Gegensatz zu Django basiert Flask auf einer Reihe von Open-Source-Softwarepaketen, von denen die wichtigsten die WSGI-Anwendungsentwicklungsbibliothek Werkzeug und die Template-Engine Jinja sind:
Strategie: Werkzeug und Jinja , wie auch Flask, wurden beide vom Pocoo-Team entwickelt. Dies spiegelt möglicherweise die ökologische Strategie von Pocoo im Wettbewerb mit Django wider. Die natürliche Erweiterung dieser Strategie besteht darin, dass das Flask-Framework keine Datenbankkomponenten enthält, weder ORM noch andere.
Fokus: Flask ist ein WSGI-Anwendungsframework, was bedeutet, dass wir bei der Entwicklung von Flask nicht auf Netzwerkvorgänge achten müssen. Der Eingang der Flask-Anwendung ist das gekapselte Netzwerkanforderungspaket und der Ausgang ist die Netzwerkantwort. Wir müssen in dieser Phase nur auf die Verarbeitungslogik achten.
WSGI-Server: Obwohl Flask über einen einfachen integrierten WSGI-Server verfügt, ist seine Leistung nur für das Debuggen während der Entwicklungsphase geeignet. Auf der offiziellen Website von Flask werden verschiedene WSGI-Server empfohlen, deren Implementierungsmethoden von Multiprozess über Multithread bis hin zu Coroutine reichen. Wir werden diese Auswahl in diesem Kurs nicht behandeln.
REST-Anpassbarkeit: Obwohl Flask und Django gleich sind, sind serverseitige dynamische Webanwendungen der erste Ausgangspunkt. Das Design von Flask macht es jedoch durchaus geeignet für die ressourcenorientierte REST-Architektur. Im Bereich der WEB-Entwicklung, wo Single-Page-Anwendungen immer mobiler und wichtiger werden, ist dies der erhebliche Vorteil von Flask gegenüber Django.
Hello Flask
Es ist ganz einfach, eine Hallo-Welt basierend auf Flask zu schreiben:
1. Importieren Sie die Flask-Klasse
from flask import Flask
Die Flask-Klasse ist die Kernklasse des Flask-Frameworks, das die WSGI-Anwendungsspezifikation implementiert.
2. Erstellen Sie eine Flask-Instanz
app = Flask(__name__)
Der erste Parameter des Flask-Konstruktors gibt einen Importnamen/Importnamen an. Das Flask-Framework verwendet diesen Namen, um statische Ressourcen, Vorlagen und Fehlermeldungen zu finden. Sofern Sie den Zweck nicht genau verstehen, sollten wir normalerweise immer die spezielle Variable _name verwenden.
Die Flask-Instanz ist aufrufbar (verfügt über eine Aufrufmethode) und diese Instanz kann sich direkt mit dem WSGI-Server verbinden.
3. Routen registrieren
@route('/') def index(): return 'Hello,Flask!'
Die Registrierung von Routen dient dazu, die Zuordnung zwischen URL-Regeln und Verarbeitungsfunktionen herzustellen. Das Flask-Framework ist auf Routing angewiesen, um die Verteilung von HTTP-Anfragen abzuschließen.
Die Funktion in der Route wird als Ansichtsfunktion bezeichnet und ihr Rückgabewert wird als Hauptinhalt der HTTP-Antwort verwendet.
4. Verbinden und starten Sie den WSGI-Server
Flask kapselt einen einfachen WSGI-Server für die Entwicklung. Wir können den Server starten, indem wir run() aufrufen:
app.run(host='0.0.0.0',port=80)
Überblick
Routing ist ein sehr wichtiges Konzept im Web-Framework der MVC-Architektur und steht auch im Mittelpunkt dieses Kurses.
Wie der Name schon sagt, bedeutet Routing, einen Weg aus der Verwirrung zu finden. Im Flask-Framework bedeutet Routing, die entsprechende Verarbeitungsfunktion für die vom Benutzer angeforderte URL zu finden.
In diesem Kurs erklären wir das Routing im Flask-Framework hauptsächlich unter folgenden Aspekten:
Wie registriere ich Routing für eine Anwendung? Wie lege ich für eine Route die von ihr unterstützten HTTP-Methoden fest? Wie passt man eine dynamische URL an? Wie filtere ich Variablentypen in URLs? Wie versteht man Zugangspunkt/Endpunkt? Wie stelle ich statisches Routing für die Anwendung ein? Wie vermeide ich, dass hartcodierte URLs auf andere Ansichten verweisen?
Route registrieren
In einer Flask-Anwendung bezieht sich Routing auf die Zuordnung zwischen der vom Benutzer angeforderten URL und der Ansichtsfunktion. Das Flask-Framework gleicht die vordefinierten URL-Regeln in der Routing-Tabelle entsprechend der URL der HTTP-Anforderung ab, findet die entsprechende Ansichtsfunktion und gibt das Ausführungsergebnis der Ansichtsfunktion an den WSGI-Server zurück:
Es ist ersichtlich, dass die Routing-Tabelle in der Flask-Anwendung eine sehr zentrale Rolle spielt. Der Inhalt der Routing-Tabelle wird vom Anwendungsentwickler gefüllt.
Routendekorator: Sie können den Routendekorator der Flask-Anwendungsinstanz verwenden, um eine URL-Regel an eine Ansichtsfunktion zu binden.
Das folgende Beispiel bindet beispielsweise die URL-Regel /test an die Ansichtsfunktion test():
@app.route('/test') def test(): return 'this is response'
Wenn diese Anwendung im Stammverzeichnis des Hosts ezhost.com bereitgestellt wird , dann Wenn ein Benutzer Folgendes besucht:
http://pythontab.com/teset
Das Flask-Framework ruft unsere test()-Funktion auf und das Rückgabeergebnis wird an den WSGI-Server übergeben und an den Besucher verschickt.
add_url_rule(): Eine andere äquivalente Schreibweise ist die Verwendung der add_url_route()-Methode der Flask-Anwendungsinstanz. Das folgende Beispiel registriert die gleiche Route wie das vorherige Beispiel:
def test(): return 'this is response' app.add_url_route('/test',view_func=test)
Tatsächlich wird die Routenregistrierung auch innerhalb des Routendekorators durch Aufruf von add_url_route implementiert ()-Methode. Aber natürlich lässt die Verwendung von Dekoratoren den Code eleganter aussehen.
Geben Sie die HTTP-Methode für die Route an
Standardmäßig unterstützt das Flask-Routing nur HTTP-GET-Anfragen. Sie können das Schlüsselwortargument „methods“ verwenden, um die von der Ansichtsmethode unterstützten HTTP-Methoden bei der Registrierung der Route explizit zu deklarieren.
Das folgende Beispiel bindet beispielsweise die URL-Regel/Authentifizierung an die Ansichtsfunktion v_auth(). Diese Route unterstützt nur die POST-Methode:
@app.route('/auth',methods=['POST']) def v_auth():pass
指定多种HTTP方法支持
关键字参数methods的类型为list,因此可以同时指定多种HTTP方法。
下面的示例中,使URL规则/user同时支持POST方法和GET方法:
@app.route('/user',methods=['POST','GET']) def v_users(): if request.method == 'GET': return ... # 返回用户列表 if request.method == 'POST' return ... #创建新用户
这个特性使Flask非常易于开发REST架构的后台服务,而不仅仅局限于传统的动态网页。
匹配动态URL
有时我们需要将同一类URL映射到同一个视图函数处理,比如,使用同一个视图函数 来显示不同用户的个人档案。我们希望以下的URL都可以分发到同一个视图函数:
在Flask中,可以将URL中的可变部分使用一对小括号声明为变量, 并为视图函数声明同名的参数:
@app.route('/user/') def v_user(uname): return '%s\'s Profile' % uname
在上面的示例中,URL规则中的表示这部分是可变的,Flask将提取用户请求的 URL中这部分的内容,并作为视图函数v_user()的uname参数进行调用。
URL变量类型过滤
考虑下面的示例,我们希望通过HTTP共享文件夹/var/readonly中的文件:
/var
/readonly
/a.txt
/b.txt
/repo
/c.txt
/d.txt
简单思考一下就有答案了。我们可以构造URL规则/file/,然后直接 读取文件内容返回给用户。注册如下的路由:
@app.route('/file/') def v_file(fname): fullname = os.path.join('/var/readonly',fname) f = open(fullname) cnt = f.read() f.close() return cnt
测试结果表明,/file/a.txt和/file/b.txt都没有问题,但是/file/repo/c.txt和 /file/repo/d.txt却会失败。
这是因为,默认情况下,在URL规则中的变量被视为不包含/的字符串。/file/repo/c.txt 是没有办法匹配URL规则/file/的。
可以使用内置的path转换器告诉Flask框架改变这一默认行为。path转换器允许 规则匹配包含/的字符串:
@app.route('/file/')
在Flask中,转换器/converter用来对从URL中提取的变量进行预处理,这个过程 发生在调用视图函数之前。Flask预置了四种转换器:
string - 匹配不包含/的字符串,这是默认的转换器
path - 匹配包含/的字符串
int - 只有当URL中的变量是整型值时才匹配,并将变量转换为整型
float - 只有当URL中的变量是浮点值时才匹配,并将变量转换为浮点型
访问点/endpoint
我们一直强调,路由的作用是根据请求的URL,找到对应的视图函数。这没错,但是在 Flask框架中,请求任务的分发并不是直接从用户请求的URL一步定位到视图函数, 两者之间隔着一个访问点/endpoint。
以下面的代码为例,我们看Flask怎样实现请求的分发:
@app.route('/home') def home():pass
在Flask内部使用两张表维护路由:
url_map :维护URL规则和endpoint的映射
view_functions :维护endpoint和视图函数的映射。
以用户访问URL/home为例,Flask将首先利用url_map找到所请求URL对应的 endpoint,即访问点home,然后再利用view_functions表查找home这个访问点 对应的视图函数,最终匹配到函数home():
默认访问点 :当我们使用route装饰器注册路由时,默认使用被装饰函数的 函数名(name)作为访问点,因此,你看到上面的表中,路由中的访问点为home。
自定义访问点 :可以在使用route装饰器或调用add_url_rule()方法注册路由时,使用 endpoint关键字参数改变这一默认行为:
1
2
@app.route('/home',endpoint='whocare')
def home():pass
此时的两张路由表将变成这样:
静态目录路由
当创建应用实例时,Flask将自动添加一条静态目录路由,其访问点 始终被设置为static,URL规则默认被设置为/static,本地路径默认被 设置为应用文件夹下的static子文件夹:
+------------------------------------------------------------+ | url rule | endpoint | view_function | | /static | static | Flask.send_static_file | +------------------------------------------------------------+ 如果你的应用目录如下:
/app
/web.py
/static
/main.css
/jquery.min.js
那么启动应用后就可以通过URL/static/main.css访问static文件夹下的main.css了。
除了访问点被固定为static,静态目录的URL规则和本地目录都是可以根据应用情况进行调整。
改变默认的本地路径 :可以在创建应用对象时使用关键字参数static_folder改变 默认的静态文件夹。例如,你的静态文件都存放在应用下的assets目录下, 那么可以按如下的方式创建应用对象:
app = Flask(name,static_folder='assets') 也可以使用一个绝对路径:
app = Flask(name,static_folder='/var/www/static') 改变默认的本地路径并不会对路由表产生影响。
改变默认的URL规则 : 如果不喜欢静态目录URL/static,也可以在创建应用 对象时使用关键字参数static_url_path换一个别的名字。
下面的示例中,将应用下的assets文件夹注册为静态目录/assets:
app = Flask(name,static_folder='assets',static_url_path='/assets') 当应用运行后,通过URL/assets/main.css就可以访问assets文件夹下的 main.css文件了。
这时的路由表变化为:
+------------------------------------------------------------+ | url | endpoint | view_function | | /assets | static | Flask.send_static_file | +------------------------------------------------------------+
构造URL
在一个实用的视图中,不可避免地存在指向其他视图的链接。在之前的课程示例中,我们 都是在视图函数中这样硬编码这些链接URL的:
@app.route('/') def v_index(): return 'tech' @app.route('/tech') def v_tech():pass
大部分情况下这种硬编码URL是可以工作的。但如果这个应用被挂在WSGI服务器的一个 子路径下,比如:/app1,那么用户访问URL/tech是不会成功的,这时应当访问/app1/tech 才可以正确地路由到视图函数v_tech()。
我们应当使用访问点让Flask框架帮我们计算链接URL。简单地给url_for()函数传入 一个访问点,它返回将是一个可靠的URL地址:
@app.route('/') def v_index(): print url_for('v_contacts') # /contact return 'see console output!' @app.route('/contact') def v_contacts():pass
添加查询参数 : 使用关键字参数,可以在构造的URL中生成查询串。下面的调用将生成 /contact?
format=json @app.route('/') def v_index(): print url_for('v_contacts',format='json') return '' @app.route('/contact') def v_contacts():pass
添加URL变量 : 如果指定访问点对应的视图函数接收参数,那么关键字参数将生成对应的参数URL。下面的 示例将生成/contact/Julia?format=html:
@app.route('/') def v_index(): print url_for('v_contact',name='Julia',format='html') return '' @app.route('/contact/') def v_contact(name):pass
添加锚点 :使用_anchor关键字可以为生成的URL添加锚点。下面的示例将生成URL /contact#part2
@app.route('/') def v_index(): print url_for('v_contacts',_anchor='part2') @app.route('/contact') def v_contacts():pass
外部URL : 默认情况下,url_for()生成站内URL,可以设置关键字参数_external 为True,生成包含站点地址的外部URL。下面的示例将生成URLhttp:///contacts:
@app.route('/') def v_index(): print url_for('v_contacts',_external=True) @app.route('/contact') def v_contacts():pass