一個簡單的Flask項目
# encoding:utf-8
from flask import Flask
'''app是一個實例,一個項目只能擁有一個實例'''
app = Flask(__name__)
'''設(shè)置為調(diào)試模式'''
app.debug = True
@app.route("/")
def hello():
'''最簡單的一個實例'''
return "Hello World"
if __name__=="__main__":
app.run()
程序解析
首先,我們導(dǎo)入了Flask類。這個類的實例將會是我們的WSGI 應(yīng)用程序
接下來,我們創(chuàng)建一個該類的實例,第一個參數(shù)是應(yīng)用模塊或者包的名稱。也就是main
我們使用route()裝飾器告訴Flask 什么樣的URL 能觸發(fā)我們的函數(shù)
這個函數(shù)的名字也在生成URL 時被特定的函數(shù)采用,這個函數(shù)返回我們想要顯示在用戶瀏覽器中的信息。
最后我們用run()函數(shù)來讓應(yīng)用運行在本地服務(wù)器上。 其中if name=='main':確保服務(wù)器只會在該腳本被Python 解釋器直接執(zhí)行的時候才會運行,而不是作為模塊導(dǎo)入的時候。
app.debug = True是將項目設(shè)置為調(diào)試模式
關(guān)閉服務(wù)器按 Ctrl + C
調(diào)試模式
第一種方式
app = Flask(__name__)
app.debug = True
第二種方式
app = Flask(__name__)
if __name__=="__main__":
app.run(debug=True)
路由裝飾器
- 本質(zhì)上就是域名后面加的一個相對路徑
路由裝飾器
@app.route('/')
def index():
return 'Index'
--------訪問方式--------
127.0.0.1:5000
@app.route('/hello/')
def hello():
return '<h1>Hello world!</h1>'
--------訪問方式--------
127.0.0.1:5000/hello/
路由裝飾器變量
@app.route('/user/<name>')
def showUserName(name):
return "User %s" %name
@app.route('/post/<int:post_id>')
def showPostId(post_id):
return "Post %d" %post_id
@app.route('/post/<float:post_id>')
def showPostId(post_id):
return "Post %f" %post_id
路由的注意點
裝飾器url的末尾必須加上/,不加容易產(chǎn)生404 Not Found
變量名必須和下面函數(shù)的參數(shù)名保持一致
如果是int或float類型,不能直接return,必須要轉(zhuǎn)換為字符串格式才可以
重定向和錯誤
from flask import redirect
@app.route("/redir/")
def redir():
return redirect("/index/")
@app.route("/redir/<name>")
def redirName(name)
return redirect(url_for("showUserName",name=name))
重定向
注意導(dǎo)包 from flask import redirect
redirect函數(shù)的作用是只要你調(diào)用了當(dāng)前函數(shù)裝飾器的url,就會重定向到redirect函數(shù)中的url中
url_for函數(shù),第一個參數(shù)重定向到的方法名,后面可以接參數(shù),第一個name為重定向到的函數(shù)的參數(shù)名,第二個參數(shù)為當(dāng)前函數(shù)參數(shù)名
反向構(gòu)建通常比硬編碼的描述性更好。允許一次性修改URL,而不用到處邊找邊改。
URL 構(gòu)建會轉(zhuǎn)義特殊字符和Unicode 數(shù)據(jù),免去你很多麻煩
錯誤
from flask import abort
@app.route("/abort/")
def abort1():
abort(404)
錯誤詳解
首先導(dǎo)包 from flask import abort
然后abort不需要return
返回碼記得不要寫錯
使用Flask-Script支持命令行選項
from flask_script import Manager
manager = Manager(app)
if __name__ == '__main__':
manager.run()
解析
導(dǎo)包Manager
使用Manager代理app
manager.run()代替app.run():替代了run里面的方法,可以直接在運行的時候加上命令參數(shù)替代run函數(shù)的參數(shù)
python hello.py runserver -d -r --host 0.0.0.0 --port 5000
命令行的參數(shù)
| 參數(shù) | 描述 |
|---|---|
| --host HOST | 設(shè)置host為 HOST |
| --port PORT | 設(shè)置port為PORT |
| -d | 設(shè)置以debug模式運行而非run模式 |
| -r | 設(shè)置自動重新載入(app.debug為True) |
請求與相應(yīng)
HTTP方法
GET方法:獲取服務(wù)器資源
POST方法:提交數(shù)據(jù)到服務(wù)器
獲取請求的headers
from flask import request
@app.route('/useragent/')
def userAgent():
user_agent=request.headers.get('User-Agent')
return "<p>Your browser %s</p>"%user_agent
響應(yīng)
@app.route('/')
def index():
return '<h1>Bad Request</h1>', 400
from flask import make_response
@app.route('/response/')
def response():
resp = make_response('<h1>Bad Request</h1>',400)
return resp
響應(yīng)解析
第一個為返回的信息,第二個為狀態(tài)碼
視圖函數(shù)直接返回一個元組(response,status,headers)
視圖函數(shù)返回一個make_resonse()函數(shù)產(chǎn)生的響應(yīng)對象
Cookies
通過請求對象的cookies屬性來訪問 Cookies
通過響應(yīng)對象的set_cookie方法來設(shè)置 Cookies
Cookies代碼
@app.route('/cookie/')
def cookie():
resp = make_response('set cookie')
resp.set_cookie('name','myname')
print(request.cookies.get('name'))
return resp
后面寫的相同的鍵會覆蓋前面的,但是不同的鍵會保留前面的
請求鉤子
before_first_request:在處理第一個請求之前運行
before_request:在每次請求之前運行
after_request:如果沒有未處理的異常拋出,在每次請求之后運行
teardown_request:即使有未處理的異常拋出,也在每次請求之后運行
請求鉤子代碼
@app.before_first_request
def beforefirst():
print("我是第一次請求之前調(diào)用的")
@app.before_request
def before():
print("我是每次請求都調(diào)用的")
@app.after_request
def after(params):
print("after_request")
@app.teardown_request
def teardown():
print("不管異常不異常,我都是每次都執(zhí)行")
模板
- 模板就是定義在template中的html文件
jinja2語法
{%... %} Jinja語句,例如判斷、循環(huán)語句
{{... }} 變量,會顯示在瀏覽器中
{#... #}注釋,不會輸出到瀏覽器中
變量規(guī)則
- {{ name }} 結(jié)構(gòu)表示一個變量,它是一種特殊的占位符
變量過濾器
| 過濾符 | 描述 |
|---|---|
| safe | 渲染值時不轉(zhuǎn)義 |
| capitalize | 把值的首字母轉(zhuǎn)換成大寫,其他字母轉(zhuǎn)換成小寫 |
| lower | 把值轉(zhuǎn)換成小寫形式 |
| upper | 把值轉(zhuǎn)換成大寫形式 |
| title | 把值中每個單詞的首字母都轉(zhuǎn)換成大寫 |
| trim | 把值的首尾空格去掉 |
| striptags | 渲染之前把值中所有的 HTML 標簽都刪掉 |
變量過濾器代碼
- {{ name | capitalize | ... }}
- 可以疊加
if語句
{% if name %}
hello,{{name}}
{% else %}
hello world
{% endif %}
for循環(huán)
<ol>
{% for a in range(10) %}
<li>{{a}}</li>
{% endfor %}
</ol>
定義函數(shù)(宏:macro)
{% macro myprint(A) %}
this is {{ A }}
{% endmacro %}
{{ myprint(A) }}
導(dǎo)入引用函數(shù)(需要調(diào)用執(zhí)行)
{% from "abc.html" import func1 %}
{{ func1(A) }}
導(dǎo)入代碼片段(不需要調(diào)用會自動執(zhí)行)
{% include 'macro.html' %}
@app.route('/include/<a>')
def includetemplate(a):
return render_template('include.html',A = a)
-------------------
macro中的代碼需要在很多地方執(zhí)行到,那就用include,只要include了,那么里面的代碼就會執(zhí)行