Flask

flask使用操作指南1


1. flask介紹

Flask是一個基于Python實現(xiàn)的web開發(fā)的'微'框架

中文文檔地址

Flask和Django一樣,也是一個基于MVC設計模式的Web框架

flask流行的主要原因:

a)有非常齊全的官方文檔疲恢,上手非常方便

b) 有非常好的拓展機制和第三方的拓展環(huán)境镇匀,工作中常見的軟件都有對應的拓展牧愁,自己動手實現(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的最小的應用

創(chuàng)建hello.py文件

from flask import Flask

app = Flask(__name__)

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

if __name__ == '__main__':

    app.run()

運行:python hello.py

3.1 初始化

from flask import Flask

app = Flask(__name__)

Flask類構造函數(shù)唯一需要的參數(shù)就是應用程序的主模塊或包。對于大多數(shù)應用程序,Python的__name__變量就是那個正確的蝙云、你需要傳遞的值。Flask使用這個參數(shù)來確定應用程序的根目錄路召,這樣以后可以相對這個路徑來找到資源文件勃刨。

3.2 路由

@app.route('/')

客戶端例如web瀏覽器發(fā)送 請求 給web服務波材,進而將它們發(fā)送給Flask應用程序實例。應用程序實例需要知道對于各個URL請求需要運行哪些代碼身隐,所以它給Python函數(shù)建立了一個URLs映射廷区。這些在URL和函數(shù)之間建立聯(lián)系的操作被稱之為 路由 。

在Flask應程序中定義路由的最便捷的方式是通過顯示定義在應用程序實例之上的app.route裝飾器贾铝,注冊被裝飾的函數(shù)來作為一個路由隙轻。

3.3 視圖函數(shù)

在上一個示例給應用程序的根URL注冊gello_world()函數(shù)作為事件的處理程序。如果這個應用程序被部署在服務器上并綁定了 www.example.com 域名垢揩,然后在你的瀏覽器地址欄中輸入 http://www.example.com 將觸發(fā)gello_world()來運行服務玖绿。客戶端接收到的這個函數(shù)的返回值被稱為 響應 叁巨。如果客戶端是web瀏覽器斑匪,響應則是顯示給用戶的文檔。

類似于gello_world()的函數(shù)被稱作 視圖函數(shù) 锋勺。

3.4 動態(tài)名稱組件路由

你的Facebook個人信息頁的URL是 http://www.facebook.com/<username> 蚀瘸,所以你的用戶名是它的一部分。Flask在路由裝飾器中使用特殊的語法支持這些類型的URLs宙刘。下面的示例定義了一個擁有動態(tài)名稱組件的路由:

@app.route('/hello/<name>')

def gello_world(name):

    return 'Hello World %s' % name

用尖括號括起來的部分是動態(tài)的部分苍姜,所以任何URLs匹配到靜態(tài)部分都將映射到這個路由。當視圖函數(shù)被調(diào)用悬包,F(xiàn)lask發(fā)送動態(tài)組件作為一個參數(shù)衙猪。在前面的示例的視圖函數(shù)中,這個參數(shù)是用于生成一個個性的問候作為響應布近。

在路由中動態(tài)組件默認為字符串垫释,但是可以定義為其他類型。例如撑瞧,路由/user/<int:id>只匹配有一個整數(shù)在id動態(tài)段的URLs棵譬。Flask路由支持int、float预伺、string订咸、path

路由匹配的規(guī)則
1.<id> :默認接受的類型是str
2.<string:id> :指定id的類型為str
3.<int:id> :指定的id類型是整性
4.<float:id> : 指定id的類型為浮點數(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 服務啟動

if __name__ == '__main__':

    app.run()

注意: __name__ == '__main__'在此處使用是用于確保web服務已經(jīng)啟動當腳本被立即執(zhí)行脏嚷。當腳本被另一個腳本導入,它被看做父腳本將啟動不同的服務瞒御,所以app.run()調(diào)用會被跳過父叙。

一旦服務啟動,它將進入循環(huán)等待請求并為之服務。這個循環(huán)持續(xù)到應用程序停止趾唱,例如通過按下Ctrl-C涌乳。

有幾個選項參數(shù)可以給app.run()配置web服務的操作模式胡诗。在開發(fā)期間哮缺,可以很方便的開啟debug模式,將激活 debugger 和 reloader 匀伏。這樣做是通過傳遞debug為True來實現(xiàn)的带欢。

app.run(host='0.0.0.0',port=8080,debug=True)

run()中參數(shù)有如下:

debug 是否開啟調(diào)試模式运授,開啟后修改python的代碼會自動重啟

port 啟動指定服務器的端口號

host主機,默認是127.0.0.1

4. 修改啟動方式乔煞,使用命令行參數(shù)啟動服務

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 浮點型
path 接受路徑逗宜,接收的時候是str,/也當做字符串的一個字符
uuid 只接受uuid字符串
any 可以同時指定多種路徑空骚,進行限定

例子:

@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'])

實現(xiàn)對應的視圖函數(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. 什么是藍圖

在Flask項目中可以用Blueprint(藍圖)實現(xiàn)模塊化的應用囤屹,使用藍圖可以讓應用層次更清晰熬甚,開發(fā)者更容易去維護和開發(fā)項目。藍圖將作用于相同的URL前綴的請求地址肋坚,將具有相同前綴的請求都放在一個模塊中乡括,這樣查找問題,一看路由就很快的可以找到對應的視圖智厌,并解決問題了诲泌。

2. 使用藍圖

2.1 安裝

pip install flask_blueprint

2.2 實例化藍圖應用

blue = Blueprint(‘first’,_ _name_ _)

注意:Blueprint中傳入了兩個參數(shù)铣鹏,第一個是藍圖的名稱敷扫,第二個是藍圖所在的包或模塊,_ name _代表當前模塊名或者包名

2.3 注冊

app = Flask(_ _name_ _)

app.register_blueprint(blue, url_prefix='/user')

注意:第一個參數(shù)即我們定義初始化定義的藍圖對象诚卸,第二個參數(shù)url_prefix表示該藍圖下葵第,所有的url請求必須以/user開始。這樣對一個模塊的url可以很好的進行統(tǒng)一管理

3 使用藍圖

修改視圖上的裝飾器合溺,修改為@blue.router(‘/’)

@blue.route('/', methods=['GET', 'POST'])
def hello():
    # 視圖函數(shù)
    return 'Hello World'

注意:該方法對應的url為127.0.0.1:5000/user/

4 url_for反向解析

語法:

url_for('藍圖中定義的第一個參數(shù).函數(shù)名', 參數(shù)名=value)

定義跳轉:

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

服務端在接收到客戶端的請求后羹幸,會自動創(chuàng)建Request對象

由Flask框架創(chuàng)建,Requesy對象不可修改

屬性:

url:完整的請求地址

base_url:去掉GET參數(shù)的url

host_url:只有主機和端口號的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對象,類字典結構對象

b)數(shù)據(jù)存儲也是key-value

1.2 form-->POST請求參數(shù)包裝

a)form是post請求參數(shù)的包裝将硝,args是一個ImmutableMultiDict對象恭朗,類字典結構對象

b)數(shù)據(jù)存儲也是key-value

重點:ImmutableMultiDict是類似字典的數(shù)據(jù)結構屏镊,但是與字典的區(qū)別是,<font style="color:red; font-weight:bold;">可以存在相同的鍵</font>痰腮。

在ImmutableMultiDict中獲取數(shù)據(jù)的方式而芥,dict['key']或者dict.get('key')或者dict.getlist('key')

image.png

2. 響應Response

Response是由開發(fā)者自己創(chuàng)建的

創(chuàng)建方法:

from flask import make_response

make_response創(chuàng)建一個響應,是一個真正的Response對象

狀態(tài)碼:

格式:make_reponse(data膀值,code)棍丐,其中data是返回的數(shù)據(jù)內(nèi)容,code是狀態(tài)碼

a)直接將內(nèi)容當做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響應,并添加返回結果的狀態(tài)碼200

@blue.route('/getresponse/')
def get_response():
    response = make_response('<h2>我是響應</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('藍圖定義的名稱.方法名')

例子1:

定義跳轉方法翘狱,跳轉到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


前言

訪問者的標識問題服務器需要識別來自同一訪問者的請求潦匈。這主要是通過瀏覽器的cookie實現(xiàn)的阱高。 訪問者在第一次訪問服務器時,服務器在其cookie中設置一個唯一的ID號——會話ID(session)茬缩。 這樣赤惊,訪問者后續(xù)對服務器的訪問頭中將自動包含該信息,服務器通過這個ID號凰锡,即可區(qū) 隔不同的訪問者未舟。

1. Cookie

概念:

a)客戶端會話技術,瀏覽器的會話技術

b)數(shù)據(jù)全部存儲在客戶端中

c)存儲使用的鍵值對結構進行存儲

特性:
    支持過期時間
    默認會自動攜帶本網(wǎng)站的cookie
    不能跨域名
    不能跨瀏覽器

創(chuàng)建:

Cookie是通過服務器創(chuàng)建的Response來創(chuàng)建的

設置:set_cookie('key', value, max_ages='', expires='')

刪除, 有三種刪除方式
    
    1. 直接清空瀏覽器的cookie
    2. delete_cookie('key') 直接使用delete_cookie函數(shù)
    3. set_cookie('key','',expires=0) 重新設置key的值為空寡夹,過期時間為0

獲却γ妗:

在每次請求中,url都會向服務器傳遞Request菩掏,在request中可以獲取到cookie的信息

request.cookies.get('name')

例子1魂角,設置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)
    # 設置cookie中的name的存在時長,設置為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ù)的一種工具斯稳,五大類型。非關系型數(shù)據(jù)庫

memcached

mongodb

sqlalchmey:那數(shù)據(jù)存到數(shù)據(jù)庫表里面

2.1 安裝

pip install flask-session

如果指定存session的類型為redis的話迹恐,需要安裝redis

pip install redis

2.2 語法

設置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進入客戶端

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ù)


image.png

注意:我們在定義app.config的時候指定了SESSION_KEY_PREFIX為flask,表示存在session中的key都會加一個前綴名flask

e) cookie和session的聯(lián)系

image.png

訪問者在第一次訪問服務器時拳氢,服務器在其cookie中設置一個唯一的ID號——會話ID(session)募逞。 這樣,訪問者后續(xù)對服務器的訪問頭中將自動包含該信息馋评,服務器通過這個ID號放接,即可區(qū) 隔不同的訪問者。然后根據(jù)不同的訪問者來獲取其中保存的value值信息栗恩。

flask使用操作指南之session實現(xiàn)登錄驗證


功能描述

使用session實現(xiàn)用戶的模擬登陸功能透乾。在前面已經(jīng)說過了,在用戶第一次訪問服務端的時候磕秤,在服務端的redis中會創(chuàng)建一個session值乳乌,在客戶端瀏覽器的cookies中也會創(chuàng)建一個session的值。該cookies中的session值和redis中的session值是一樣的市咆,那么在往后的訪問操作中汉操,請求request都會傳遞給后端,后端在獲取到request的時候蒙兰,其實就是獲取到了request.cookies中的session的值了磷瘤,那么就可以做登錄的校驗了。校驗功能如下:

素材地址

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.如果驗證成功,就向session中保存用戶的id值挠他。如果沒有登錄成功的話扳抽,那就對session不做任何的處理,直接跳轉到登錄頁面上去殖侵。

@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ù)庫校驗贸呢,用戶密碼是否正確
        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的茉唉。那么驗證用戶是否登錄了固蛾,其實就是驗證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_login
def index():
    return render_template('index.html')

flask使用操作指南之模板


1. jinja2

Flask中使用jinja2模板引擎

jinja2是由Flask作者開發(fā),模仿Django的模板引擎

優(yōu)點:

速度快魏铅,被廣泛使用

HTML設計和后端python分離

非常靈活昌犹,快速和安全

提供了控制,繼承等高級功能

2. 模板語法

2.1 模板語法主要分為兩種:變量和標簽

模板中的變量:{{ var }}

視圖傳遞給模板的數(shù)據(jù)

前面定義出來的數(shù)據(jù)

變量不存在览芳,默認忽略

模板中的標簽:{% tag %}

控制邏輯

使用外部表達式

創(chuàng)建變量

宏定義

2.2 結構標簽:

block

{% block xxx %}

{% endblock %}

塊操作
    父模板挖坑,子模板填坑

extends

{% extends ‘xxx.html’ %}

繼承以后保留塊中的內(nèi)容
{{ super() }}

挖坑繼承體現(xiàn)的化整為零的操作

macro

{% macro hello(name) %}

    {{ name }}

{% endmacro %}

宏定義鸿竖,可以在模板中定義函數(shù)沧竟,在其他地方調(diào)用

宏定義可導入

{% from 'xxx' import xxx %}

例子1:

在index.html中定義macro標簽,定義一個方法缚忧,然后去調(diào)用方法悟泵,結果是展示商品的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.first

loop.last

loop.index

loop.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ù))

首先: 在頁面中進行解析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 單詞反轉

format

striptags 渲染之前朽肥,將值中標簽去掉

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 定義基礎模板base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {% block title %}
        {% endblock %}
    </title>
    <script src="https://code.jquery.com/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 定義基礎模板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默認并沒有提供任何數(shù)據(jù)庫操作的API

我們可以選擇任何適合自己項目的數(shù)據(jù)庫來使用

Flask中可以自己的選擇數(shù)據(jù),用原生語句實現(xiàn)功能持钉,也可以選擇ORM(SQLAlchemy衡招,MongoEngine)

SQLAlchemy是一個很強大的關系型數(shù)據(jù)庫框架,支持多種數(shù)據(jù)庫后臺每强。SQLAlchemy提供了高層ORM始腾,也提供了使用數(shù)據(jù)庫原生SQL的低層功能。

ORM:

將對對象的操作轉換為原生SQL
優(yōu)點
    易用性空执,可以有效減少重復SQL
    性能損耗少
    設計靈活浪箭,可以輕松實現(xiàn)復雜查詢
    移植性好

針對于Flask的支持,官網(wǎng)地址

pip install flask-sqlalchemy

安裝驅動

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表示默認值

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)建定義模型中對應到數(shù)據(jù)庫中的表

db.drop_all()表示刪除數(shù)據(jù)庫中的所有的表

4. 初始化SQLALchemy

在定義的init.py文件中使用SQLALchemy去整合一個或多個Flask的應用

有兩種方式:

第一種:

from flask_sqlalchemy import SQLALchemy

app = Flask(__name__)
db = SQLAlchemy(app)

第二種:

from App.models import db

def 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/database

dialect數(shù)據(jù)庫實現(xiàn)

driver數(shù)據(jù)庫的驅動

例子:
訪問mysql數(shù)據(jù)庫,驅動為pymysql邢羔,用戶為root驼抹,密碼為123456,數(shù)據(jù)庫的地址為本地拜鹤,端口為3306框冀,數(shù)據(jù)庫名稱HelloFlask

設置如下: "mysql+pymysql://root:123456@localhost:3306/HelloFlask"

在初始化init.py文件中如下配置:

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:123456@localhost:3306/HelloFlask"

6. 對學生數(shù)據(jù)進行CRUD操作

語法:

類名.query.xxx

獲取查詢集:

all()

filter(類名.屬性名==xxx)

filter_by(屬性名=xxx)

數(shù)據(jù)操作:

在事務中處理,數(shù)據(jù)插入

db.session.add(object)

db.session.add_all(list[object])

db.session.delete(object)

db.session.commit()

修改和刪除基于查詢

6.1 想學生表中添加數(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 '添加成功'

提交事務敏簿,使用commit提交我們的添加數(shù)據(jù)的操作

6.2 獲取所有學生信息

將學生的全部信息獲取到明也,并且返回給頁面宣虾,在頁面中使用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的學生的信息

寫法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 修改學生的信息

寫法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 刪除一個學生的信息

寫法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后的結果是一個list的結果集

<b>重點注意:在增刪改中如果不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):
        # 實例化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)
    # 提交事務到數(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 查--使用運算符

獲取查詢集

filter(類名.屬性名.運算符(‘xxx’))

filter(類名.屬性 數(shù)學運算符  值)

運算符:

contains: 包含
startswith:以什么開始
endswith:以什么結束
in_:在范圍內(nèi)
like:模糊
__gt__: 大于
__ge__:大于等于
__lt__:小于
__le__:小于等于

篩選:

offset()

limit()

order_by()

get()

first()

paginate()

邏輯運算:

與
    and_
    filter(and_(條件),條件…)

或
    or_
    filter(or_(條件),條件…)

非
    not_
    filter(not_(條件),條件…)

例子1:

  1. 查詢學生的id為3鹉胖,4,5够傍,6甫菠,16的的學生信息,使用<b>in_邏輯運算</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)
  1. 查詢學生的年齡小于18歲的學生的信息

     Student.query.filter(Student.s_age < 18)
    
  2. 查詢學生的年齡小于18歲的學生的信息冕屯,<b>__lt__小于</b>

     students = Student.query.filter(Student.s_age.__lt__(15))
    
  3. 查詢學生的年齡小于等于18歲的學生的信息寂诱,<b>__le__小于等于</b>

     students = Student.query.filter(Student.s_age.__le__(15))
    
  4. 查詢學生的姓名以什么開始或者以什么結尾的學生的信息<b>startswith和endswith</b>

     students = Student.query.filter(Student.s_name.startswith('張'))
     students = Student.query.filter(Student.s_name.endswith('2'))
    
  5. 查詢id=4的學生的信息

     Student.query.get(4)
     獲取的結果是學生的對象
    
  6. 模糊搜索like

     %:代表一個或者多個
     _:代表一個
     
     Student.query.filter(Student.s_name.like('%張%')) 
    
  7. 分頁,查詢第二頁的數(shù)據(jù)4條

     第一個參數(shù)是那一頁安聘,第二個參數(shù)是一頁的條數(shù)痰洒,第三個參數(shù)是是否輸出錯誤信息
     students = Student.query.paginate(2, 4, False).items
    

例子2:

跳過offset幾個信息,截取limit結果的幾個值

# 按照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的學生
stus = Student.query.filter(Student.s_id==24)
stus = Student.query.get(24)

例子3:

  1. 查詢

    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的學生

    stus = Student.query.filter(not_(Student.s_name.contains('可愛')),
    not_(Student.s_age == 12))

例子4:

<b>分頁:</b>


image.png

后端數(shù)據(jù)處理:

# 方法一:手動實現(xiàn)分頁,使用offset和limit
page = 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ù)多少囱桨,默認為10條
per_page = int(request.args.get('per_page', 10))

# 查詢當前第幾個的多少條數(shù)據(jù)
paginate = Student.query.order_by('-s_id').paginate(page, per_page, error_out=False)

stus = paginate.items

前端數(shù)據(jù)展示:

<h2>學生信息</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>
當前頁數(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. 關聯(lián)關系

2.1 一對多建立模型

學生模型:

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則是在對關聯(lián)的兩個表進行join操作搀继,從而獲取到所有相關的對象。

dynamic則不一樣翠语,在訪問屬性的時候叽躯,并沒有在內(nèi)存中加載數(shù)據(jù),而是返回一個query對象, 需要執(zhí)行相應方法才可以獲取對象肌括,

2.2

  1. 通過班級查詢學生信息
    @grade.route('/selectstubygrade/<int:id>/')
    
    def select_stu_by_grade(id):
        grade = Grade.query.get(id)
        # 通過班級對象.定義的relationship變量去獲取學生的信息
        stus = grade.students
    
        return render_template('grade_student.html',
                               stus=stus,
                               grade=grade
                               )
  1. 通過學生信息查詢班級信息
    @stu.route('/selectgradebystu/<int:id>/')

    def select_grade_by_stu(id):

        stu = Student.query.get(id)
        # 通過學生對象.定義的backref參數(shù)去獲取班級的信息
        grade = stu.stu
    
        return render_template('student_grade.html',
                               grade=grade,
                               stu=stu)

注意:表的外鍵由db.ForeignKey指定点骑,傳入的參數(shù)是表的字段。db.relations它聲明的屬性不作為表字段谍夭,第一個參數(shù)是關聯(lián)類的名字黑滴,backref是一個反向身份的代理,相當于在Student類中添加了stu的屬性。例如紧索,有Grade實例dept和Student實例stu袁辈。dept.students.count()將會返回學院學生人數(shù);stu.stu.first()將會返回學生的學院信息的Grade類實例。一般來講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進行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. 關聯(liá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)建學生類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>齐邦,我們不需要關心這張表,因為這張表將會由SQLAlchemy接管第租,它唯一的作用是作為students表和courses表關聯(lián)表,所以必須在db.relationship()中指出<font style="color:red;">sencondary關聯(lián)表參數(shù)</font>我纪。lazy是指查詢時的惰性求值的方式慎宾,這里有詳細的參數(shù)說明,而db.backref是聲明反向身份代理浅悉,其中的lazy參數(shù)是指明反向查詢的惰性求值方式.

2. 添加學生和課程之間的關系

通過頁面中傳遞學生的id和課程的id趟据,分別獲取學生的對象和課程的對象,在使用關聯(lián)關系append去添加學生對象术健,并且add以后再commit后汹碱,就可以在中間表sc中查看到新增的關聯(liá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. 刪除學生和課程之間的關系

通過頁面獲取傳遞的學生的id和課程的id荞估,分別獲取學生對象和課程對象咳促,在使用關聯(lián)關系remove去刪除學生對象,并commit將事務提交到數(shù)據(jù)庫中

stu = Student.query.get(s_id)
cou = Course.query.get(c_id)

cou.students.remove(stu)
db.session.commit()

4. 通過課程查詢學生的信息

以下定義在課程course的模型中勘伺,所以通過課程查詢學生的信息跪腹,<font style="color:red;">語法為課程的對象.studengs</font>。如果知道學生的信息反過來找課程的信息飞醉,則使用backref的反向關聯(lián)去查詢冲茸,<font style="color:red;">語語法為學生的對象.cou(反向)</font>

students = db.relationship('Student',secondary=sc,backref='cou')

cou = Course.query.get(2)
stus = cou.students

5. 通過學生去查詢課程的信息

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 Flask

from flask_debugtoolbar import DebugToolbarExtension

app = Flask(__name__)

app.debug = True

app.config['SECRET_KEY'] = '<replace with a secret key>'

toolbar = DebugToolbarExtension(app)

2. restful

Flask-RESTful 提供的最主要的基礎就是資源(resources)缅帘。資源(Resources)是構建在 Flask 可拔插視圖 之上轴术,只要在你的資源(resource)上定義方法就能夠容易地訪問多個 HTTP 方法

官網(wǎng)上描述了一個最簡單的restful風格的api,如下:

from flask import Flask
from 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)對象中钦无,設置如下配置

from flask_restful import Api

api = Api()

api.init_app(app=app)

在views中需要引入配置的api還有Resource

# 導入包和restful中的Api對象
from flask_restful import Resource
from 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 = ['大學英語', '大學物理', '線性代數(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': '刪除成功'}


# 綁定處理url
api.add_resource(CreateCourse, '/api/course/<int:id>/', '/api/course/')

2.3 端點(Endpoints)

在一個 API 中,你的資源可以通過多個 URLs 訪問铃诬。你可以把多個 URLs 傳給 Api 對象的 Api.add_resource() 方法祭陷。每一個 URL 都能訪問到你的 Resource

如:

api.add_resource(CreateCourse, '/api/course/<int:id>/', '/api/course/')

2.4 返回響應

Flask-RESTful 支持視圖方法多種類型的返回值苍凛。同 Flask 一樣,你可以返回任一迭代器兵志,它將會被轉換成一個包含原始 Flask 響應對象的響應醇蝴。Flask-RESTful 也支持使用多個返回值來設置響應代碼和響應頭

如:

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.revcounter
jiaja2中沒有ifequal

2. 耦合

Django: 大而全想罕,但是耦合性高悠栓。Auth,Permission按价,admin基本沒用
        開發(fā)快惭适,符合MVC模式

Flask: 微框架,很小巧楼镐。需要哪些功能癞志,自己裝。
        需要熟悉MVC模式

3. 模型

3.1 模型定義

1. 模型中不定義數(shù)據(jù)庫的表名:
    在django中默認表名為:'應用app名_模型名小寫'
    在flask中默認的表名為:'模型名小寫'

2. 自增id字段:
    在django中默認會創(chuàng)建自增的主鍵id
    在flask中需要自己寫自增的主鍵id:
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)

3. 查詢所有數(shù)據(jù)的結果框产,all()方法
    在django中查詢的結果為QuerySet
    在Flask中查詢結果為List

4. 查詢滿足條件的數(shù)據(jù)的結果凄杯,filter(), filter_by()方法
    在django中查詢的結果為QuerySet
    在Flask中查詢結果為BaseQuery objects

3.2 模型數(shù)據(jù)查詢

Django:

一對多:

  模型1: u 字段為 FOREIGN_KEY,關聯(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秉宿,關聯(lián)到模型2
    模型2: yy字段戒突,定義relationship字段, backref=‘uu’

    模型1查找模型2:
        模型2對象 = 模型1對象.uu
        模型1對象 = 模型2對象.yy
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末描睦,一起剝皮案震驚了整個濱河市膊存,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌忱叭,老刑警劉巖隔崎,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異窑多,居然都是意外死亡仍稀,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門埂息,熙熙樓的掌柜王于貴愁眉苦臉地迎上來技潘,“玉大人,你說我怎么就攤上這事千康∠碛模” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵拾弃,是天一觀的道長值桩。 經(jīng)常有香客問我,道長豪椿,這世上最難降的妖魔是什么奔坟? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任携栋,我火速辦了婚禮,結果婚禮上咳秉,老公的妹妹穿的比我還像新娘婉支。我一直安慰自己,他們只是感情好澜建,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布向挖。 她就那樣靜靜地躺著,像睡著了一般炕舵。 火紅的嫁衣襯著肌膚如雪何之。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天咽筋,我揣著相機與錄音溶推,去河邊找鬼。 笑死奸攻,一個胖子當著我的面吹牛悼潭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播舞箍,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼皆疹!你這毒婦竟也來了疏橄?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤略就,失蹤者是張志新(化名)和其女友劉穎捎迫,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體表牢,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡窄绒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了崔兴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片彰导。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖敲茄,靈堂內(nèi)的尸體忽然破棺而出位谋,到底是詐尸還是另有隱情,我是刑警寧澤堰燎,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布掏父,位于F島的核電站,受9級特大地震影響秆剪,放射性物質(zhì)發(fā)生泄漏赊淑。R本人自食惡果不足惜爵政,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望陶缺。 院中可真熱鬧钾挟,春花似錦、人聲如沸组哩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伶贰。三九已至蛛砰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間黍衙,已是汗流浹背泥畅。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留琅翻,地道東北人位仁。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像方椎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子棠众,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容