1. flask介紹
Flask是一個基于Python實(shí)現(xiàn)的web開發(fā)的'微'框架
中文文檔地址
Flask和Django一樣,,也是一個基于MVC設(shè)計模式的Web框架
flask流行的主要原因:
a)有非常齊全的官方文檔,上手非常方便
b) 有非常好的拓展機(jī)制和第三方的拓展環(huán)境,,工作中常見的軟件都有對應(yīng)的拓展,,自己動手實(shí)現(xiàn)拓展也很容易
c) 微型框架的形式給了開發(fā)者更大的選擇空間
2. 安裝flask
2.1虛擬環(huán)境搭建
virtualenv --no-site-packages falskenv
激活windows下虛擬環(huán)境cd Scripts
activate
2.2 安裝
pip install flask
3. 基于flask的最小的應(yīng)用
創(chuàng)建hello.py文件
from flask import Flask
app = Flask(__name__)@app.route('/')def gello_world():
return 'Hello World'if __name__ == '__main__':
app.run()
運(yùn)行:python hello.py
3.1 初始化
from flask import Flask
app = Flask(__name__)
Flask類構(gòu)造函數(shù)唯一需要的參數(shù)就是應(yīng)用程序的主模塊或包。對于大多數(shù)應(yīng)用程序,Python的__name__變量就是那個正確的,、你需要傳遞的值,。Flask使用這個參數(shù)來確定應(yīng)用程序的根目錄,這樣以后可以相對這個路徑來找到資源文件,。
3.2 路由
@app.route('/')
客戶端例如web瀏覽器發(fā)送 請求 給web服務(wù),,進(jìn)而將它們發(fā)送給Flask應(yīng)用程序?qū)嵗?yīng)用程序?qū)嵗枰缹τ诟鱾€URL請求需要運(yùn)行哪些代碼,,所以它給Python函數(shù)建立了一個URLs映射,。這些在URL和函數(shù)之間建立聯(lián)系的操作被稱之為 路由 。
在Flask應(yīng)程序中定義路由的最便捷的方式是通過顯示定義在應(yīng)用程序?qū)嵗系腶pp.route裝飾器,,注冊被裝飾的函數(shù)來作為一個路由,。
3.3 視圖函數(shù)
在上一個示例給應(yīng)用程序的根URL注冊gello_world()函數(shù)作為事件的處理程序。如果這個應(yīng)用程序被部署在服務(wù)器上并綁定了 www. 域名,,然后在你的瀏覽器地址欄中輸入 http://www. 將觸發(fā)gello_world()來運(yùn)行服務(wù),。客戶端接收到的這個函數(shù)的返回值被稱為 響應(yīng) ,。如果客戶端是web瀏覽器,,響應(yīng)則是顯示給用戶的文檔。
類似于gello_world()的函數(shù)被稱作 視圖函數(shù) ,。
3.4 動態(tài)名稱組件路由
你的Facebook個人信息頁的URL是 http://www./<username> ,,所以你的用戶名是它的一部分。Flask在路由裝飾器中使用特殊的語法支持這些類型的URLs,。下面的示例定義了一個擁有動態(tài)名稱組件的路由:
@app.route('/hello/<name>')def gello_world(name): return 'Hello World %s' % name
用尖括號括起來的部分是動態(tài)的部分,,所以任何URLs匹配到靜態(tài)部分都將映射到這個路由。當(dāng)視圖函數(shù)被調(diào)用,,F(xiàn)lask發(fā)送動態(tài)組件作為一個參數(shù),。在前面的示例的視圖函數(shù)中,這個參數(shù)是用于生成一個個性的問候作為響應(yīng),。
在路由中動態(tài)組件默認(rèn)為字符串,,但是可以定義為其他類型。例如,,路由/user/<int:id>只匹配有一個整數(shù)在id動態(tài)段的URLs,。Flask路由支持int、float,、string,、path
路由匹配的規(guī)則
1.<id> :默認(rèn)接受的類型是str
2.<string:id> :指定id的類型為str
3.<int:id> :指定的id類型是整性
4.<float:id> : 指定id的類型為浮點(diǎn)數(shù)(四舍五入,,且不能接收整數(shù)類型)
5.<path:path1> : 指定接收的path為url中的路徑
如下:
@blue.route('/get_id/<id>/')def get_id(id): #匹配str類型的id值
return 'id: %s' % id
@blue.route('/get_int_id/<int:id>/')def get_int_id(id): #匹配int類型的id值
return 'id:%d' % id
@blue.route('/get_float/<float:uid>/')def get_float(uid): #匹配float類型的值,,不能匹配int類型(四舍五入)
return 'uid:%.2f' %uid
@blue.route('/get_path/<path:upath>/')def get_path(upath): #匹配url路徑
return 'path:%s' % upath
3.5 服務(wù)啟動
if __name__ == '__main__':
app.run()
注意: __name__ == '__main__'在此處使用是用于確保web服務(wù)已經(jīng)啟動當(dāng)腳本被立即執(zhí)行,。當(dāng)腳本被另一個腳本導(dǎo)入,它被看做父腳本將啟動不同的服務(wù),,所以app.run()調(diào)用會被跳過,。
一旦服務(wù)啟動,,它將進(jìn)入循環(huán)等待請求并為之服務(wù),。這個循環(huán)持續(xù)到應(yīng)用程序停止,例如通過按下Ctrl-C,。
有幾個選項(xiàng)參數(shù)可以給app.run()配置web服務(wù)的操作模式,。在開發(fā)期間,可以很方便的開啟debug模式,,將激活 debugger 和 reloader ,。這樣做是通過傳遞debug為True來實(shí)現(xiàn)的。
app.run(host='0.0.0.0',port=8080,debug=True)
run()中參數(shù)有如下:
debug 是否開啟調(diào)試模式,,開啟后修改python的代碼會自動重啟port 啟動指定服務(wù)器的端口號host主機(jī),,默認(rèn)是127.0.0.1
4. 修改啟動方式,使用命令行參數(shù)啟動服務(wù)
4.1 安裝插件
pip install flask-script
調(diào)整代碼
manager = Manager(app=‘自定義的flask對象’)
啟動的地方
manager.run()
4.2 啟動命令
python hellow.py runserver -h 地址 -p 端口 -d -r
其中:-h表示地址,。-p表示端口,。-d表示debug模式。-r表示自動重啟
如:manager.run(python xx.py runserver -h 0.0.0.0 -p 8080 -d)
5. route規(guī)則
5.1 規(guī)則
寫法:<converter:variable_name>
converter類型:
string 字符串int 整形float 浮點(diǎn)型
path 接受路徑,,接收的時候是str,,/也當(dāng)做字符串的一個字符
uuid 只接受uuid字符串
any 可以同時指定多種路徑,進(jìn)行限定
例子:
@app.route('/helloint/<int:id>/')@app.route('/getfloat/<float:price>/')@app.route('/getstr/<string:name>/',,methods=['GET', 'POST'])@app.route('/getpath/<path:url_path>/')@app.route('/getbyuuid/<uuid:uu>/',,methods=['GET', 'POST'])
實(shí)現(xiàn)對應(yīng)的視圖函數(shù):
@blue.route('/hello/<name>/')def hello_man(name):
print(type(name)) return 'hello name:%s type:%s' % (name, type(name))
@blue.route('/helloint/<int:id>/')def hello_int(id):
print(id)
print(type(id)) return 'hello int: %s' % (id)
@blue.route('/index/')def index(): return render_template('hello.html')
@blue.route('/getfloat/<float:price>/')def hello_float(price): return 'float: %s' % price
@blue.route('/getstr/<string:name>/')def hello_name(name): return 'hello name: %s' % name
@blue.route('/getpath/<path:url_path>/')def hello_path(url_path): return 'path: %s' % url_path
@blue.route('/getuuid/')def gello_get_uuid():
a = uuid.uuid4() return str(a)
@blue.route('/getbyuuid/<uuid:uu>/')def hello_uuid(uu): return 'uu:%s' % uu
5.2 methods請求方法
常用的請求類型有如下幾種
GET : 獲取
POST : 創(chuàng)建
PUT : 修改(全部屬性都修改)
DELETE : 刪除
PATCH : 修改(修改部分屬性)
定義url的請求類型:
@blue.route('/getrequest/', methods=['GET', 'POST'])
flask使用操作指南2
1. 什么是藍(lán)圖
在Flask項(xiàng)目中可以用Blueprint(藍(lán)圖)實(shí)現(xiàn)模塊化的應(yīng)用,使用藍(lán)圖可以讓應(yīng)用層次更清晰,,開發(fā)者更容易去維護(hù)和開發(fā)項(xiàng)目,。藍(lán)圖將作用于相同的URL前綴的請求地址,將具有相同前綴的請求都放在一個模塊中,,這樣查找問題,,一看路由就很快的可以找到對應(yīng)的視圖,并解決問題了,。
2. 使用藍(lán)圖
2.1 安裝
pip install flask_blueprint
2.2 實(shí)例化藍(lán)圖應(yīng)用
blue = Blueprint(‘first’,_ _name_ _)
注意:Blueprint中傳入了兩個參數(shù),,第一個是藍(lán)圖的名稱,,第二個是藍(lán)圖所在的包或模塊,_ name _代表當(dāng)前模塊名或者包名
2.3 注冊
app = Flask(_ _name_ _)
app.register_blueprint(blue, url_prefix='/user')
注意:第一個參數(shù)即我們定義初始化定義的藍(lán)圖對象,,第二個參數(shù)url_prefix表示該藍(lán)圖下,,所有的url請求必須以/user開始。這樣對一個模塊的url可以很好的進(jìn)行統(tǒng)一管理
3 使用藍(lán)圖
修改視圖上的裝飾器,,修改為@blue.router(‘/’)
@blue.route('/', methods=['GET', 'POST'])def hello(): # 視圖函數(shù)
return 'Hello World'
注意:該方法對應(yīng)的url為127.0.0.1:5000/user/
4 url_for反向解析
語法:
url_for('藍(lán)圖中定義的第一個參數(shù).函數(shù)名', 參數(shù)名=value)
定義跳轉(zhuǎn):
from flask import url_for, redirect@blue.route('/redirect/')def make_redirect():
# 第一種方法
return redirect('/hello/index/') # 第二種方法
return redirect(url_for('first.index'))
flask使用操作指南3
1. 請求request
服務(wù)端在接收到客戶端的請求后,,會自動創(chuàng)建Request對象
由Flask框架創(chuàng)建,,Requesy對象不可修改
屬性:
url:完整的請求地址
base_url:去掉GET參數(shù)的url
host_url:只有主機(jī)和端口號的url
path:路由中的路徑
method:請求方法
remote_addr:請求的客戶端的地址
args:GET請求參數(shù)
form:POST請求參數(shù)
files:文件上傳
headers:請求頭
cookies:請求中的cookie
1.1 args-->GET請求參數(shù)包裝
a)args是get請求參數(shù)的包裝,args是一個ImmutableMultiDict對象,,類字典結(jié)構(gòu)對象
b)數(shù)據(jù)存儲也是key-value
1.2 form-->POST請求參數(shù)包裝
a)form是post請求參數(shù)的包裝,,args是一個ImmutableMultiDict對象,類字典結(jié)構(gòu)對象
b)數(shù)據(jù)存儲也是key-value
重點(diǎn):ImmutableMultiDict是類似字典的數(shù)據(jù)結(jié)構(gòu),,但是與字典的區(qū)別是,,<font style="color:red; font-weight:bold;">可以存在相同的鍵</font>。
在ImmutableMultiDict中獲取數(shù)據(jù)的方式,,dict['key']或者dict.get('key')或者dict.getlist('key')
2. 響應(yīng)Response
Response是由開發(fā)者自己創(chuàng)建的
創(chuàng)建方法:
from flask import make_response
make_response創(chuàng)建一個響應(yīng),,是一個真正的Response對象
狀態(tài)碼:
格式:make_reponse(data,code),,其中data是返回的數(shù)據(jù)內(nèi)容,,code是狀態(tài)碼
a)直接將內(nèi)容當(dāng)做make_response的第一個參數(shù),第二個參數(shù)直接寫返回的狀態(tài)碼
b)直接在render后加返回的狀態(tài)碼
例子1:
定義一個獲取GET請求的request的方法,,并將返回成功的請求的狀態(tài)碼修改為200
@blue.route('/getrequest/', methods=['GET'])def get_request():
print(request) return '獲取request', 200
例子2:
返回response響應(yīng),,并添加返回結(jié)果的狀態(tài)碼200
@blue.route('/getresponse/')def get_response():
response = make_response('<h2>我是響應(yīng)</h2>', 500) return response
或者:
@blue.route('/getresponse/', methods=['GET'])def get_user_response():
login_html = render_template('login.html')
res = make_response(login_html, 200) return res
3. 重定向/反向解析
url_for('藍(lán)圖定義的名稱.方法名')
例子1:
定義跳轉(zhuǎn)方法,跳轉(zhuǎn)到get_response的方法上
@blue.route('/getredirect/')def get_redirect(): return redirect('getresponse')
例子2:
使用url_for反向解析
from flask import redirect, url_for@blue.route('/getredirect/')def get_redirect():
return redirect(url_for('first.get_response'))
4. 終止/異常捕獲
自動拋出異常:abort(狀態(tài)碼)
捕獲異常處理:errorhandler(狀態(tài)碼),,定義的函數(shù)中要包含一個參數(shù),,用于接收異常信息
4.1 定義終止程序
@blue.route('/make_abort/')def get_abort():
abort(400) return '終止'
4.2 捕獲定義的異常
@blue.errorhandler(400)def handler(exception):
return '捕獲到異常信息:%s' % exception
flask使用操作指南之session/cookie
前言
訪問者的標(biāo)識問題服務(wù)器需要識別來自同一訪問者的請求。這主要是通過瀏覽器的cookie實(shí)現(xiàn)的,。 訪問者在第一次訪問服務(wù)器時,,服務(wù)器在其cookie中設(shè)置一個唯一的ID號——會話ID(session)。 這樣,,訪問者后續(xù)對服務(wù)器的訪問頭中將自動包含該信息,,服務(wù)器通過這個ID號,即可區(qū) 隔不同的訪問者,。
1. Cookie
概念:
a)客戶端會話技術(shù),,瀏覽器的會話技術(shù)
b)數(shù)據(jù)全部存儲在客戶端中
c)存儲使用的鍵值對結(jié)構(gòu)進(jìn)行存儲
特性:
支持過期時間
默認(rèn)會自動攜帶本網(wǎng)站的cookie
不能跨域名
不能跨瀏覽器
創(chuàng)建:
Cookie是通過服務(wù)器創(chuàng)建的Response來創(chuàng)建的
設(shè)置:set_cookie('key', value, max_ages='', expires='')
刪除, 有三種刪除方式
1. 直接清空瀏覽器的cookie
2. delete_cookie('key') 直接使用delete_cookie函數(shù)
3. set_cookie('key','',expires=0) 重新設(shè)置key的值為空,過期時間為0
獲?。?/p>
在每次請求中,,url都會向服務(wù)器傳遞Request,在request中可以獲取到cookie的信息
request.cookies.get('name')
例子1,,設(shè)置cookie:
import datetime@blue.route('/setcookie/')def set_cookie():
temp = render_template('index.html')
response = make_response(temp)
outdate=datetime.datetime.today() + datetime.timedelta(days=30) # 設(shè)置cookie中的name的存在時長,,設(shè)置為30天才過期
response.set_cookie('name','cocoococo',expires=outdate) return response
例子2,刪除cookie中的值
@blue.route('/setcookie/')def set_cookie():
temp = render_template('index.html')
response = make_response(temp) # 第一種方式,,通過set_cookie去刪除
response.set_cookie('name','',expires=0) # 第二種方式,,del_cookie刪除
response.del_cookie('name') return response
例子3,獲取cookie中的值
@blue.route('/getcookie/')
def get_cookie():
name=request.cookies.get('name')
return name
2. Session
flask-session是flask框架的session組件
該組件則將支持session保存到多個地方
如:
redis:保存數(shù)據(jù)的一種工具,,五大類型,。非關(guān)系型數(shù)據(jù)庫
memcached
mongodb
sqlalchmey:那數(shù)據(jù)存到數(shù)據(jù)庫表里面
2.1 安裝
pip install flask-session
如果指定存session的類型為redis的話,,需要安裝redis
pip install redis
2.2 語法
設(shè)置session:
session['key'] = value
讀取session:
result = session['key'] :如果內(nèi)容不存在,將會報異常
result = session.get('key') :如果內(nèi)容不存在,,將返回None
刪除session:
session.pop('key')
清空session中所有數(shù)據(jù):
session.clear()
2.2 使用
我們在初始化文件中創(chuàng)建一個方法,,通過調(diào)用該方法來獲取到Flask的app對象
def create_app():
app = Flask(__name__) # SECRET_KEY 秘鑰
app.config['SECRET_KEY'] = 'secret_key'
# session類型為redis
app.config['SESSION_TYPE'] = 'redis'
# 添加前綴
app.config['SESSION_KEY_PREFIX'] = 'flask'
# 加載app的第一種方式
se = Session()
se.init_app(app=app) #加載app的第二種方式
Session(app=app)
app.register_blueprint(blueprint=blue) return app
2.3 案例
定義一個登陸的方法,post請求獲取到username,,直接寫入到redis中,,并且在頁面中展示出redis中的username
a)需要先啟動redis,開啟redis-server,,使用redis-cli進(jìn)入客戶端
b)定義方法
@blue.route('/login/', methods=['GET', 'POST'])def login(): if request.method == 'GET':
username = session.get('username') return render_template('login.html', username=username) else:
username = request.form.get('username')
session['username'] = username return redirect(url_for('first.login'))
c)定義模板
<body><h3>歡迎:{{ username }}</h3><form action="" method="POST">
用戶名:<input type="text" name="username" placeholder="請輸入你的名字">
<input type="submit" value="提交"></form></body>
d)redis中數(shù)據(jù)
注意:我們在定義app.config的時候指定了SESSION_KEY_PREFIX為flask,,表示存在session中的key都會加一個前綴名flask
e) cookie和session的聯(lián)系
訪問者在第一次訪問服務(wù)器時,服務(wù)器在其cookie中設(shè)置一個唯一的ID號——會話ID(session),。 這樣,,訪問者后續(xù)對服務(wù)器的訪問頭中將自動包含該信息,服務(wù)器通過這個ID號,,即可區(qū) 隔不同的訪問者,。然后根據(jù)不同的訪問者來獲取其中保存的value值信息。
flask使用操作指南之session實(shí)現(xiàn)登錄驗(yàn)證
功能描述
使用session實(shí)現(xiàn)用戶的模擬登陸功能,。在前面已經(jīng)說過了,,在用戶第一次訪問服務(wù)端的時候,在服務(wù)端的redis中會創(chuàng)建一個session值,,在客戶端瀏覽器的cookies中也會創(chuàng)建一個session的值,。該cookies中的session值和redis中的session值是一樣的,那么在往后的訪問操作中,,請求request都會傳遞給后端,,后端在獲取到request的時候,其實(shí)就是獲取到了request.cookies中的session的值了,,那么就可以做登錄的校驗(yàn)了,。校驗(yàn)功能如下:
素材地址
1. 前端login.html頁面
登錄頁面就兩個輸入框,分別接收用戶名和密碼
<dd class="user_icon"> <input type="text" name="username" placeholder="賬號" class="login_txtbx"/>
</dd>
<dd class="pwd_icon"> <input type="password" name="password" placeholder="密碼" class="login_txtbx"/>
</dd>
2. 后端方法
模擬用戶的登錄,,直接判斷用戶的名稱為妲己以及密碼為123123.如果驗(yàn)證成功,,就向session中保存用戶的id值。如果沒有登錄成功的話,,那就對session不做任何的處理,,直接跳轉(zhuǎn)到登錄頁面上去。
@app_blue.route('/new_login/', methods=['GET', 'POST'])def new_login(): if request.method == 'GET': return render_template('login.html') else:
username = request.form.get('username')
password = request.form.get('password') # 數(shù)據(jù)庫校驗(yàn),,用戶密碼是否正確
if username == '妲己' and password == '123123':
session['user_id'] = 1
return redirect((url_for('first.index'))) else:
return redirect(url_for('first.new_login'))
@app_blue.route('/index/', methods=['GET'])
def index():
return render_template('index.html')
3. 裝飾器
使用裝飾器去裝飾我們的index()函數(shù),,如果用戶登錄了,,則session中有user_id的key,,如果沒有登錄的話,,session中是沒有user_id的key的。那么驗(yàn)證用戶是否登錄了,,其實(shí)就是驗(yàn)證session的user_id
def is_login(func): @wraps(func)
def check_login(*args, **kwargs):
if 'user_id' in session: return func(*args, **kwargs) else: return redirect(url_for('first.new_login')) return check_login
4. 修改index()函數(shù),,使用裝飾器裝飾
@app_blue.route('/index/', methods=['GET'])
@is_logindef index(): return render_template('index.html')
flask使用操作指南之模板
1. jinja2
Flask中使用jinja2模板引擎
jinja2是由Flask作者開發(fā),模仿Django的模板引擎
優(yōu)點(diǎn):
速度快,,被廣泛使用
HTML設(shè)計和后端python分離
非常靈活,,快速和安全
提供了控制,繼承等高級功能
2. 模板語法
2.1 模板語法主要分為兩種:變量和標(biāo)簽
模板中的變量:{{ var }}
視圖傳遞給模板的數(shù)據(jù)
前面定義出來的數(shù)據(jù)
變量不存在,,默認(rèn)忽略
模板中的標(biāo)簽:{% tag %}
控制邏輯
使用外部表達(dá)式
創(chuàng)建變量
宏定義
2.2 結(jié)構(gòu)標(biāo)簽:
block
{% block xxx %}
{% endblock %}
塊操作
父模板挖坑,,子模板填坑
extends
{% extends ‘xxx.html’ %}
繼承以后保留塊中的內(nèi)容
{{ super() }}
挖坑繼承體現(xiàn)的化整為零的操作
macro
{% macro hello(name) %} {{ name }}
{% endmacro %}
宏定義,可以在模板中定義函數(shù),,在其他地方調(diào)用
宏定義可導(dǎo)入
{% from 'xxx' import xxx %}
例子1:
在index.html中定義macro標(biāo)簽,,定義一個方法,然后去調(diào)用方法,,結(jié)果是展示商品的id和商品名稱
{% macro show_goods(id, name) %}
商品id:{{ id }}
商品名稱:{{ name }}
{% endmacro %}
{{ show_goods('1', '娃哈哈') }}
<br>
{{ show_goods('2', '雪碧') }}
例子2:
在index.html頁面中定義一個say()方法,,然后解析該方法:
{% macro say() %} <h3>今天天氣氣溫回升</h3>
<h3>適合去游泳</h3>
<h3>適合去郊游</h3>{% endmacro %}
{{ say() }}
例子3:
定義一個function.html中定義一個方法:
{% macro create_user(name) %}
創(chuàng)建了一個用戶:{{ name }}
{% endmacro %}
在index.html中引入function.html中定義的方法
{% from 'functions.html' import create_user %}
{{ create_user('小花') }}
2.3 循環(huán)
{% for item in cols %}
aa
{% else %}
bb
{% endfor %}
也可以獲取循環(huán)信息loop
loop.firstloop.lastloop.indexloop.revindex
例子:
在視圖中定義一個視圖函數(shù):
@stu.route('/scores/')def scores():
scores_list = [21,34,32,67,89,43,22,13]
content_h2 = '<h2>今天你們真帥</h2>'
content_h3 = ' <h3>今天你們真帥</h3> '
return render_template('scores.html',
scores=scores_list,
content_h2=content_h2,
content_h3=content_h3)
(該視圖函數(shù),在下面講解的過濾器中任然使用其返回的content_h2等參數(shù))
首先: 在頁面中進(jìn)行解析scores的列表,。題目要求:第一個成績展示為紅色,,最后一個成績展示為綠色,其他的不變
<ul>
{% for score in scores %}
{% if loop.first %} <li style="color:red;">{{ loop.revindex }}:{{ loop.index }}:{{ score }}</li>
{% elif loop.last %} <li style="color:green;">{{ loop.revindex }}:{{ loop.index }}:{{ score }}</li>
{% else %} <li> {{ loop.revindex }}:{{ loop.index }}:{{ score }}</li>
{% endif %}
{% endfor %}</ul>
2.4 過濾器
語法:
{{ 變量|過濾器|過濾器... }}
capitalize 單詞首字母大寫
lower 單詞變?yōu)樾?/p>
upper 單詞變?yōu)榇髮?/p>
title
trim 去掉字符串的前后的空格
reverse 單詞反轉(zhuǎn)
format
striptags 渲染之前,,將值中標(biāo)簽去掉
safe 講樣式渲染到頁面中
default
last 最后一個字母
first
length
sum
sort
例子:
<ul>
<li>{{ content_h2 }}</li>
<li>{{ content_h2|safe }}</li>
<li>{{ content_h2|striptags }}</li>
<li>{{ content_h3 }}</li>
<li>{{ content_h3|length }}</li>
<li>{{ content_h3|trim|safe }}</li>
<li>{{ content_h3|trim|length }}</li></ul>
3. 定義模板
3.1 定義基礎(chǔ)模板base.html
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<title>
{% block title %}
{% endblock %} </title>
<script src="https://code./jquery-3.2.1.min.js"></script>
{% block extCSS %}
{% endblock %}</head><body>{% block header %}
{% endblock %}
{% block content%}
{% endblock %}
{% block footer%}
{% endblock %}
{% block extJS %}
{% endblock %}</body></html>
3.2 定義基礎(chǔ)模板base_main.html
{% extends 'base.html' %}
{% block extCSS %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
{% endblock %}
4. 靜態(tài)文件信息配置
<b>django</b>:
第一種方式:
{% load static %}
<link rel="stylesheet" href="{% static 'css/index.css' %}">
第二種方式:
<link rel="stylesheet" href="/static/css/index.css">
<b>flask</b>:
第一種方式:
<link rel="stylesheet" href="/static/css/index.css">
第二種方式:
<link rel="stylesheet" href="{{ url_for('static', filename='css/index.css') }}">
flask使用操作指南之模型1
1. Flask模型
Flask默認(rèn)并沒有提供任何數(shù)據(jù)庫操作的API
我們可以選擇任何適合自己項(xiàng)目的數(shù)據(jù)庫來使用
Flask中可以自己的選擇數(shù)據(jù),,用原生語句實(shí)現(xiàn)功能,也可以選擇ORM(SQLAlchemy,,MongoEngine)
SQLAlchemy是一個很強(qiáng)大的關(guān)系型數(shù)據(jù)庫框架,,支持多種數(shù)據(jù)庫后臺。SQLAlchemy提供了高層ORM,,也提供了使用數(shù)據(jù)庫原生SQL的低層功能,。
ORM:
將對對象的操作轉(zhuǎn)換為原生SQL
優(yōu)點(diǎn)
易用性,可以有效減少重復(fù)SQL
性能損耗少
設(shè)計靈活,,可以輕松實(shí)現(xiàn)復(fù)雜查詢
移植性好
針對于Flask的支持,,官網(wǎng)地址
pip install flask-sqlalchemy
安裝驅(qū)動
pip install pymysql
2. 定義模型
使用SQLALchemy的對象去創(chuàng)建字段
其中tablename指定創(chuàng)建的數(shù)據(jù)庫的名稱
創(chuàng)建models.py文件,其中定義模型from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Student(db.Model):
s_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
s_name = db.Column(db.String(16), unique=True)
s_age = db.Column(db.Integer, default=1)
__tablename__ = "student"
其中:
Integer表示創(chuàng)建的s_id字段的類型為整形,,
primary_key表示是否為主鍵
String表示該字段為字符串
unique表示該字段唯一
default表示默認(rèn)值
autoincrement表示是否自增
3. 創(chuàng)建數(shù)據(jù)表
在視圖函數(shù)中我們引入models.py中定義的db
from App.models import db@blue.route("/createdb/")def create_db():
db.create_all() return "創(chuàng)建成功"@blue.route('/dropdb/')def drop_db():
db.drop_all() return '刪除成功'
其中: db.create_all()表示創(chuàng)建定義模型中對應(yīng)到數(shù)據(jù)庫中的表
db.drop_all()表示刪除數(shù)據(jù)庫中的所有的表
4. 初始化SQLALchemy
在定義的init.py文件中使用SQLALchemy去整合一個或多個Flask的應(yīng)用
有兩種方式:
第一種:from flask_sqlalchemy import SQLALchemy
app = Flask(__name__)
db = SQLAlchemy(app)
第二種:from App.models import dbdef create_app():
app = Flask(__name__)
db.init_app(app) return app
5. 配置數(shù)據(jù)庫的訪問地址
官網(wǎng)配置參數(shù)
數(shù)據(jù)庫連接的格式:
dialect+driver://username:password@host:port/databasedialect數(shù)據(jù)庫實(shí)現(xiàn)
driver數(shù)據(jù)庫的驅(qū)動
例子:
訪問mysql數(shù)據(jù)庫,,驅(qū)動為pymysql,用戶為root,,密碼為123456,,數(shù)據(jù)庫的地址為本地,端口為3306,,數(shù)據(jù)庫名稱HelloFlask
設(shè)置如下: "mysql+pymysql://root:123456@localhost:3306/HelloFlask"
在初始化init.py文件中如下配置:
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = Falseapp.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:123456@localhost:3306/HelloFlask"
6. 對學(xué)生數(shù)據(jù)進(jìn)行CRUD操作
語法:
類名.query.xxx
獲取查詢集:
all()
filter(類名.屬性名==xxx)
filter_by(屬性名=xxx)
數(shù)據(jù)操作:
在事務(wù)中處理,,數(shù)據(jù)插入db.session.add(object)db.session.add_all(list[object])db.session.delete(object)db.session.commit()
修改和刪除基于查詢
6.1 想學(xué)生表中添加數(shù)據(jù)
@blue.route('/createstu/')def create_stu():
s = Student()
s.s_name = '小花%d' % random.randrange(100)
s.s_age = '%d' % random.randrange(30)
db.session.add(s)
db.session.commit() return '添加成功'
提交事務(wù),,使用commit提交我們的添加數(shù)據(jù)的操作
6.2 獲取所有學(xué)生信息
將學(xué)生的全部信息獲取到,并且返回給頁面,,在頁面中使用for循環(huán)去解析即可
@blue.route("/getstudents/")def get_students():
students = Student.query.all() return render_template("StudentList.html", students=students)
6.3 獲取s_id=1的學(xué)生的信息
寫法1:
students = Student.query.filter(Student.s_id==1)
寫法2:
students = Student.query.filter_by(s_id=2)
注意:filter中可以接多個過濾條件
寫法3:
sql = 'select * from student where s_id=1'students = db.session.execute(sql)
6.4 修改學(xué)生的信息
寫法1:
students = Student.query.filter_by(s_id=3).first()
students.s_name = '哈哈'db.session.commit()
寫法2:
Student.query.filter_by(s_id=3).update({'s_name':'娃哈哈'})
db.session.commit()
6.5 刪除一個學(xué)生的信息
寫法1:
students = Student.query.filter_by(s_id=2).first()
db.session.delete(students)
db.session.commit()
寫法2:
students = Student.query.filter_by(s_id=1).all()
db.session.delete(students[0])
db.session.commit()
注意:filter_by后的結(jié)果是一個list的結(jié)果集
<b>重點(diǎn)注意:在增刪改中如果不commit的話,,數(shù)據(jù)庫中的數(shù)據(jù)并不會更新,只會修改本地緩存中的數(shù)據(jù),,所以一定需要db.session.commit()</b>
flask使用操作指南之模型2
1. 深入數(shù)據(jù)庫增刪改查
定義模型,,并定義初始化的函數(shù):
class Student(db.Model):
s_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
s_name = db.Column(db.String(16), unique=True)
s_age = db.Column(db.Integer, default=1)
__tablename__ = "student"
def __init__(self, name, age):
self.s_name = name
self.s_age = age
1.1 增--批量增加
第一種方式:
@blue.route('/createstus/')def create_users():
stus = [] for i in range(5): # 實(shí)例化Student的對象
s = Student() # 對象的屬性賦值
s.s_name = '張三%s' % random.randrange(10000)
s.s_age = '%d' % random.randrange(100)
stus.append(s) # 添加需要創(chuàng)建的數(shù)據(jù)
db.session.add_all(stus) # 提交事務(wù)到數(shù)據(jù)庫
db.session.commit() return '創(chuàng)建成功'
注:在創(chuàng)建單條數(shù)據(jù)的時候使用db.session.add(),在創(chuàng)建多條數(shù)據(jù)的時候使用db.session.add_all()
第二種方式:
@blue.route('/createstus/')def create_users():
stus = [] for i in range(5): # 使用類的初始化去創(chuàng)建Student對象
s = Student('張三%s' % random.randrange(10000), '%d' % random.randrange(100))
stus.append(s)
db.session.add_all(stus)
db.session.commit() return '創(chuàng)建成功'
1.2 查--使用運(yùn)算符
獲取查詢集
filter(類名.屬性名.運(yùn)算符(‘xxx’))
filter(類名.屬性 數(shù)學(xué)運(yùn)算符 值)
運(yùn)算符:
contains: 包含
startswith:以什么開始
endswith:以什么結(jié)束in_:在范圍內(nèi)
like:模糊__gt__: 大于
__ge__:大于等于
__lt__:小于
__le__:小于等于
篩選:
offset()limit()
order_by()
get()
first()
paginate()
邏輯運(yùn)算:
與 and_
filter(and_(條件),條件…)
或 or_
filter(or_(條件),條件…)
非 not_
filter(not_(條件),條件…)
例子1:
查詢學(xué)生的id為3,,4,,5,6,,16的的學(xué)生信息,,使用<b>in_邏輯運(yùn)算</b>
@blue.route('/getstubyids/') def get_stu_by_ids():
students = Student.query.filter(Student.s_id.in_([3,4,5,6,16])) return render_template('StudentList.html', students=students)
查詢學(xué)生的年齡小于18歲的學(xué)生的信息
Student.query.filter(Student.s_age < 18)
查詢學(xué)生的年齡小于18歲的學(xué)生的信息,<b>__lt__小于</b>
students = Student.query.filter(Student.s_age.__lt__(15))
查詢學(xué)生的年齡小于等于18歲的學(xué)生的信息,,<b>__le__小于等于</b>
students = Student.query.filter(Student.s_age.__le__(15))
查詢學(xué)生的姓名以什么開始或者以什么結(jié)尾的學(xué)生的信息<b>startswith和endswith</b>
students = Student.query.filter(Student.s_name.startswith('張'))
students = Student.query.filter(Student.s_name.endswith('2'))
查詢id=4的學(xué)生的信息
Student.query.get(4)
獲取的結(jié)果是學(xué)生的對象
模糊搜索like
%:代表一個或者多個
_:代表一個
Student.query.filter(Student.s_name.like('%張%'))
分頁,,查詢第二頁的數(shù)據(jù)4條
第一個參數(shù)是那一頁,第二個參數(shù)是一頁的條數(shù),,第三個參數(shù)是是否輸出錯誤信息
students = Student.query.paginate(2, 4, False).items
例子2:
跳過offset幾個信息,,截取limit結(jié)果的幾個值
# 按照id降序排列stus = Student.query.order_by('-s_id')# 按照id升序排列stus = Student.query.order_by('s_id')
stus = Student.query.order_by(asc('s_id'))
stus = Student.query.order_by('s_id asc')# 按照id降序獲取三個stus = Student.query.order_by('-s_id').limit(3)
stus = Student.query.order_by('s_id desc').limit(3)
from sqlalchemy import desc
stus = Student.query.order_by(desc('s_id')).limit(3)# 獲取年齡最大的一個stus = Student.query.order_by('-s_age').first()# 跳過3個數(shù)據(jù),查詢5個信息stus = Student.query.order_by('-s_age').offset(3).limit(5)# 跳過3個數(shù)據(jù)stus = Student.query.order_by('-s_age').offset(3)# 獲取id等于24的學(xué)生stus = Student.query.filter(Student.s_id==24)
stus = Student.query.get(24)
例子3:
查詢
from sqlalchemy import and_, or_, not_
<b>查詢多個條件</b>
stus = Student.query.filter(Student.s_age==18, Student.s_name=='雅典娜')
<b>and_ 并且條件</b>
stus = Student.query.filter(and_(Student.s_age==18, Student.s_name=='雅典娜'))
<b>or_ 或者條件</b>
stus = Student.query.filter(or_(Student.s_age==18, Student.s_name=='火神'))
<b>not_ 非</b>
stus = Student.query.filter(not_(Student.s_age==18), Student.s_name=='火神')
查詢姓名不包含'可愛‘,,并且年齡不等于12的學(xué)生
stus = Student.query.filter(not_(Student.s_name.contains('可愛')),
not_(Student.s_age == 12))
例子4:
<b>分頁:</b>
后端數(shù)據(jù)處理:
# 方法一:手動實(shí)現(xiàn)分頁,,使用offset和limitpage = int(request.args.get('page', 1))
stus = Student.query.offset((page-1)*5).limit(5)# 方法二: 使用切片[:]s_page = (page - 1)*5
e_page = page * 5
stus = Student.query.all()[s_page: e_page]# 方法三:使用paginate# 查詢第幾頁的數(shù)據(jù) page = int(request.args.get('page', 1))# 每一頁的條數(shù)多少,默認(rèn)為10條per_page = int(request.args.get('per_page', 10))# 查詢當(dāng)前第幾個的多少條數(shù)據(jù)paginate = Student.query.order_by('-s_id').paginate(page, per_page, error_out=False)
stus = paginate.items
前端數(shù)據(jù)展示:
<h2>學(xué)生信息</h2>{% for stu in stus %}
id:{{ stu.s_id }}
姓名:{{ stu.s_name }}
年齡:{{ stu.s_age }} <br>{% endfor %}<br>總頁數(shù): {{ paginate.pages }}<br>一共{{ paginate.total }}條數(shù)據(jù)<br>當(dāng)前頁數(shù):{{ paginate.page }}<br>{% if paginate.has_prev %} <a href="/stupage/?page={{ paginate.prev_num }}">上一頁</a>:{{ paginate.prev_num }}
{% endif %}
{% if paginate.has_next %} <a href="/stupage/?page={{ paginate.next_num }}">下一頁</a>:{{ paginate.next_num }}
{% endif %}<br><br>頁碼:{% for i in paginate.iter_pages() %} <a href="/stupage/?page={{ i }}">{{ i }}</a>
{% endfor %}
2. 關(guān)聯(lián)關(guān)系
2.1 一對多建立模型
學(xué)生模型:
class Student(db.Model):
s_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
s_name = db.Column(db.String(20), unique=True)
s_age = db.Column(db.Integer, default=18)
s_g = db.Column(db.Integer, db.ForeignKey('grade.g_id'), nullable=True)
__tablename__ = 'student'
班級模型:
class Grade(db.Model):
g_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
g_name = db.Column(db.String(10), unique=True)
g_desc = db.Column(db.String(100), nullable=True)
g_time = db.Column(db.Date, default=datetime.now)
students = db.relationship('Student', backref='stu', lazy=True)
__tablename__ = 'grade'
官網(wǎng)解釋有如下幾個lazy的參數(shù):
lazy 決定了 SQLAlchemy 什么時候從數(shù)據(jù)庫中加載數(shù)據(jù):,,有如下四個值:
<b>select</b>/True: (which is the default) means that SQLAlchemy will load the data as necessary in one go using a standard select statement.
<b>joined</b>/False: tells SQLAlchemy to load the relationship in the same query as the parent using a JOIN statement.
<b>subquery</b>: works like ‘joined’ but instead SQLAlchemy will use a subquery.
<b>dynamic</b>: is special and useful if you have many items. Instead of loading the items SQLAlchemy will return another query object which
you can further refine before loading the items. This is usually what you want if you expect more than a handful of items for this relationship
select就是訪問到屬性的時候,,就會全部加載該屬性的數(shù)據(jù)。
joined則是在對關(guān)聯(lián)的兩個表進(jìn)行join操作,,從而獲取到所有相關(guān)的對象,。
dynamic則不一樣,在訪問屬性的時候,,并沒有在內(nèi)存中加載數(shù)據(jù),,而是返回一個query對象, 需要執(zhí)行相應(yīng)方法才可以獲取對象,
2.2
通過班級查詢學(xué)生信息
@grade.route('/selectstubygrade/<int:id>/')
def select_stu_by_grade(id):
grade = Grade.query.get(id) # 通過班級對象.定義的relationship變量去獲取學(xué)生的信息
stus = grade.students
return render_template('grade_student.html',
stus=stus,
grade=grade
)
通過學(xué)生信息查詢班級信息
@stu.route('/selectgradebystu/<int:id>/') def select_grade_by_stu(id):
stu = Student.query.get(id) # 通過學(xué)生對象.定義的backref參數(shù)去獲取班級的信息
grade = stu.stu
return render_template('student_grade.html',
grade=grade,
stu=stu)
注意:表的外鍵由db.ForeignKey指定,,傳入的參數(shù)是表的字段,。db.relations它聲明的屬性不作為表字段,第一個參數(shù)是關(guān)聯(lián)類的名字,,backref是一個反向身份的代理,相當(dāng)于在Student類中添加了stu的屬性,。例如,有Grade實(shí)例dept和Student實(shí)例stu。dept.students.count()將會返回學(xué)院學(xué)生人數(shù);stu.stu.first()將會返回學(xué)生的學(xué)院信息的Grade類實(shí)例,。一般來講db.relationship()會放在一這一邊,。
3. 數(shù)據(jù)庫遷移
在django中繼承了makemigrations,可以通過migrate操作去更新數(shù)據(jù)庫,,修改我們定義的models,然后在將模型映射到數(shù)據(jù)庫中,。
在flask中也有migrate操作,,它能跟蹤模型的變化,并將變化映射到數(shù)據(jù)庫中
2.1 安裝migrate
pip install flask-migrate
2.2 配置使用migrate
2.2.1 初始化,,使用app和db進(jìn)行migrate對象的初始化
from flask_migrate import Migrate#綁定app和數(shù)據(jù)庫Migrate(app=app, db=db)
2.2.2 安裝了flask-script的話,,可以在Manager()對象上添加遷移指令
from flask_migrate import Migrate, MigrateCommand
app = Flask(__name__)
manage = Manager(app=app)
manage.add_command('db', MigrateCommand)
操作:
python manage.py db init 初始化出migrations的文件,只調(diào)用一次python manage.py db migrate 生成遷移文件python manage.py db upgrade 執(zhí)行遷移文件中的升級python manage.py db downgrade 執(zhí)行遷移文件中的降級python manage.py db --help 幫助文檔
flask使用操作指南之模型3
1. 關(guān)聯(lián)關(guān)系---多對多
定義模型:
引入SLALchemy
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
創(chuàng)建中間表
sc = db.Table('sc',
db.Column('s_id', db.Integer, db.ForeignKey('student.s_id'), primary_key=True),
db.Column('c_id', db.Integer, db.ForeignKey('courses.c_id'), primary_key=True)
)
創(chuàng)建學(xué)生類Student
class Student(db.Model):
s_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
s_name = db.Column(db.String(20), unique=True)
s_age = db.Column(db.Integer, default=18)
s_g = db.Column(db.Integer, db.ForeignKey('grade.g_id'), nullable=True)
__tablename__ = 'student'
def __init__(self, name, age):
self.s_name = name
self.s_age = age
self.s_g = None
創(chuàng)建課程表的模型,,Course類
class Course(db.Model):
c_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
c_name = db.Column(db.String(20), unique=True)
students = db.relationship('Student',
secondary=sc,
backref='cou')
__tablename__ = 'courses'
def __init__(self, name):
self.c_name = name
sc表由<font style="color:red;">db.Table聲明</font>,,我們不需要關(guān)心這張表,因?yàn)檫@張表將會由SQLAlchemy接管,,它唯一的作用是作為students表和courses表關(guān)聯(lián)表,,所以必須在db.relationship()中指出<font style="color:red;">sencondary關(guān)聯(lián)表參數(shù)</font>。lazy是指查詢時的惰性求值的方式,,這里有詳細(xì)的參數(shù)說明,,而db.backref是聲明反向身份代理,其中的lazy參數(shù)是指明反向查詢的惰性求值方式.
2. 添加學(xué)生和課程之間的關(guān)系
通過頁面中傳遞學(xué)生的id和課程的id,,分別獲取學(xué)生的對象和課程的對象,,在使用關(guān)聯(lián)關(guān)系append去添加學(xué)生對象,并且add以后再commit后,,就可以在中間表sc中查看到新增的關(guān)聯(lián)關(guān)系了,。
userid = request.form.get('userid')
courseid = request.form.get('courseid')
stu = Student.query.get(userid)
cou = Course.query.get(courseid)
cou.students.append(stu)
db.session.add(cou)
db.session.commit()
3. 刪除學(xué)生和課程之間的關(guān)系
通過頁面獲取傳遞的學(xué)生的id和課程的id,分別獲取學(xué)生對象和課程對象,,在使用關(guān)聯(lián)關(guān)系remove去刪除學(xué)生對象,,并commit將事務(wù)提交到數(shù)據(jù)庫中
stu = Student.query.get(s_id)
cou = Course.query.get(c_id)
cou.students.remove(stu)
db.session.commit()
4. 通過課程查詢學(xué)生的信息
以下定義在課程course的模型中,所以通過課程查詢學(xué)生的信息,,<font style="color:red;">語法為課程的對象.studengs</font>,。如果知道學(xué)生的信息反過來找課程的信息,則使用backref的反向關(guān)聯(lián)去查詢,,<font style="color:red;">語語法為學(xué)生的對象.cou(反向)</font>
students = db.relationship('Student',secondary=sc,backref='cou')
cou = Course.query.get(2)
stus = cou.students
5. 通過學(xué)生去查詢課程的信息
stu = Student.query.get(id)
cous = stu.cou
flask使用操作指南之插件
1. 開發(fā),,頁面調(diào)試工具debugtoolbar
1.1 安裝
pip install flask-debugtoolbar
1.2 配置
from flask import Flaskfrom flask_debugtoolbar import DebugToolbarExtension
app = Flask(__name__)
app.debug = Trueapp.config['SECRET_KEY'] = '<replace with a secret key>'toolbar = DebugToolbarExtension(app)
2. restful
Flask-RESTful 提供的最主要的基礎(chǔ)就是資源(resources)。資源(Resources)是構(gòu)建在 Flask 可拔插視圖 之上,,只要在你的資源(resource)上定義方法就能夠容易地訪問多個 HTTP 方法
官網(wǎng)上描述了一個最簡單的restful風(fēng)格的api,,如下:
from flask import Flaskfrom flask.ext import restful
app = Flask(__name__)
api = restful.Api(app)class HelloWorld(restful.Resource):
def get(self):
return {'hello': 'world'}
api.add_resource(HelloWorld, '/')if __name__ == '__main__':
app.run(debug=True)
2.1 安裝
pip install flask_restful
2.2 配置
在create_app()獲取Flask(name)對象中,設(shè)置如下配置
from flask_restful import Api
api = Api()
api.init_app(app=app)
在views中需要引入配置的api還有Resource
# 導(dǎo)入包和restful中的Api對象from flask_restful import Resourcefrom utils.functions import api# 定義類,啟動包含了對數(shù)據(jù)處理的GET,POST,PATCH,PUT,DELETE請求class CreateCourse(Resource):def get(self, id):
course = Course.query.get(id) return course.to_dict()def post(self):
courses = ['大學(xué)英語', '大學(xué)物理', '線性代數(shù)', '高數(shù)', 'VHDL', 'ARM', '馬克思主義', '農(nóng)場勞動']
course_list = [] for course in courses:
c = Course()
c.c_name = course
course_list.append(c)
db.session.add_all(course_list)
db.session.commit()
courses = Course.query.all() return [course.to_dict() for course in courses]def patch(self, id):
c_name = request.form.get('c_name')
course = Course.query.get(id)
course.c_name = c_name
db.session.commit() return {'code': 200, 'data': course.to_dict(), 'msg': '請求成功'}def delete(self, id):
course = Course.query.get(id)
db.session.delete(course)
db.session.commit() return {'code': 200, 'msg': '刪除成功'}# 綁定處理urlapi.add_resource(CreateCourse, '/api/course/<int:id>/', '/api/course/')
2.3 端點(diǎn)(Endpoints)
在一個 API 中,,你的資源可以通過多個 URLs 訪問,。你可以把多個 URLs 傳給 Api 對象的 Api.add_resource() 方法。每一個 URL 都能訪問到你的 Resource
如:
api.add_resource(CreateCourse, '/api/course/<int:id>/', '/api/course/')
2.4 返回響應(yīng)
Flask-RESTful 支持視圖方法多種類型的返回值,。同 Flask 一樣,,你可以返回任一迭代器,它將會被轉(zhuǎn)換成一個包含原始 Flask 響應(yīng)對象的響應(yīng),。Flask-RESTful 也支持使用多個返回值來設(shè)置響應(yīng)代碼和響應(yīng)頭
如:
def get(self, id):
course = Course.query.get(id) return course.to_dict(), 200
Django和Flask區(qū)別:
1. jiaji2和DjangoTemplates模板引擎相比,,jiaja2語法更簡單
比如: loop.index 和 forloop.counter
loop.revindex 和 forloop.revcounterjiaja2中沒有ifequal
2. 耦合
Django: 大而全,但是耦合性高,。Auth,,Permission,admin基本沒用
開發(fā)快,,符合MVC模式
Flask: 微框架,,很小巧。需要哪些功能,,自己裝,。
需要熟悉MVC模式
3. 模型
3.1 模型定義
1. 模型中不定義數(shù)據(jù)庫的表名:
在django中默認(rèn)表名為:'應(yīng)用app名_模型名小寫'
在flask中默認(rèn)的表名為:'模型名小寫'2. 自增id字段:
在django中默認(rèn)會創(chuàng)建自增的主鍵id
在flask中需要自己寫自增的主鍵id:
id = db.Column(db.Integer, primary_key=True, autoincrement=True)3. 查詢所有數(shù)據(jù)的結(jié)果,all()方法
在django中查詢的結(jié)果為QuerySet
在Flask中查詢結(jié)果為List4. 查詢滿足條件的數(shù)據(jù)的結(jié)果,,filter(), filter_by()方法
在django中查詢的結(jié)果為QuerySet
在Flask中查詢結(jié)果為BaseQuery objects
3.2 模型數(shù)據(jù)查詢
Django:
一對多:
模型1: u 字段為 FOREIGN_KEY,,關(guān)聯(lián)到模型2
模型1.u = u對象
模型1.u_id = u對象.id
模型1查找模型2的數(shù)據(jù)
模型2對象=模型1對象.u
模型1對象=模型2對象.模型1_set.all()
一對一:
模型1查找模型2的數(shù)據(jù)
模型2對象=模型1對象.u
模型1對象=模型2對象.模型1.all()
Flask:
一對多:
模型1: u字段為FOREIGN KEY,關(guān)聯(lián)到模型2
模型2: yy字段,,定義relationship字段,, backref=‘uu’
模型1查找模型2:
模型2對象 = 模型1對象.uu
模型1對象 = 模型2對象.yy