flask 之(二) --- 視圖|模版|模型

 

Flask框架

  打開pycharm編譯器,新建一個Flask項目,選擇提早建好的虛擬環境 。css

  項目結構:html

    static:靜態資源文件,能夠直接被瀏覽器訪問前端

    templates:模版文件,必須在項目的python代碼中進行渲染給前端,瀏覽器纔可訪問python

    app.py:python的程序文件mysql

  返回信息:能夠是字符串、html標籤、模版golang

  請求流程:sql

    Flask對象註冊的路由數據庫

    路由映射給相應函數django

    函數進行和數據交互編程

    數據進行展現給前端

 1 from flask import Flask
 2 
 3 app = Flask(__name__)
 4 
 5 @app.route('/')
 6 def hello_world():
 7     return 'Hello World!'
 8 
 9 if __name__ == '__main__':
10     app.run()  # 默認只能本機訪問。app.run(host='0.0.0.0',debug=True)
 11 12 """ 運行:在Terminal終端中進入到項目的文件夾下,鍵入python app.py運行 """

視圖函數 

狀態碼http

  2xx:請求成功

  3xx:重定向

  4xx:客戶端錯誤

  5xx:服務器錯誤

路由route

 1 from flask import Flask, render_template
 2 app = Flask(__name__)
 3 
 4 @app.route("/orders/",methods=["GET", "POST"]) # 能夠請求的方式爲:GET、POST。默認只支持get請求方法,想要支持其餘方法須要設置 methods=['請求方法'] 參數
 5 def orders():
 6     return "Orders"
 7 
 8 @app.route("/users/")
 9 def users():
10     return "<h1>Users</h1>"                 # 返回的能夠是html標籤
11 
12 @app.route('/index/')
13 def hello_world():
14 
15     result = render_template("index.html")  # 對模版進行渲染,爲返回給前端做準備
16     print(result)                           # 獲取打印的是html標籤字符串
17     return result                           # 返回給前端頁面展現
18 
19 @app.route("/goods/<any(a,b):id>/")         # 路由能夠是/goods/a;也能夠是/goods/b
20 def goods(id):                  # 能夠將路徑中的信息以參數的形式傳給試圖函數 21 
22     print(id)
23     print(type(id))
24     return "Goods Info"
25 
26 if __name__ == '__main__':
27     app.run(host="0.0.0.0", debug=True, port=5000)

 在run( )中,啓動前還能夠添加參數 

  • debug:    是否開啓調試模式,debug=True表示開啓後修改python代碼會自動重啓
  • host:   主機,默認是127.0.0.1,表示本機。指定爲 '0.0.0.0'表明全部ip均可訪問
  • port:       啓動指定服務器的端口號,默認5000
  • threaded: 是否開啓多線程

 在@app.route('/path/<param>/')中,參數默認param 是字符串類型,也能夠設置以下類型:

  • str:      遇到‘/’就中止匹配
  • path:   能夠匹配任意字符
  • int:      整數型
  • float:   浮點數
  • uuid:    惟一標示
  • any:    列舉出一些中的某一個

 在@app.route('/path/<param>/',methods=["GET", "POST"])中,methods參數默認是get。想要支持其餘方法須要設置 methods=['請求方法'] 參數

  • GET:      拿,獲取。從服務器獲取數據獲取資源
  • POST:    提交,建立、認證。用來向服務器提交數據
  • DELETE:刪除數據。告訴服務器要刪除某些數據
  • PUT:      提交,全量更新。用來向服務器提交數據,一般PUT用來更新數據。需更新全部的字段信息
  • PATCH: 提交,差量更新。用來向服務器提交數據,一般PATCH用來更新數據,只更新變動的字段信息  

  在pycharm中的Tools的RESTful Web Service能夠動態模擬各類請求

視圖views

  •  Request 

  request全局對象: 客戶端發送給服務器的數據請求後。Flask根據客戶端的請求報文自動生成request對象,request對象不可修改

  客戶端發送的請求- 裏面包含了客戶端的各類信息- Request不是客戶端建立的- 是框架根據客戶端的數據(請求報文)建立的- 屬於Flask中的內置對象

  request屬性:

    request.url:           完整請求地址

    request.base_url:   去掉GET參數的url

    request.host_url:    只有主機和端口號的url

    request.path:         路由中的路徑

    request.method:    請求方式

    request.remote_addr: 請求的客戶端地址

    request.args:     GET請求參數

    request.form:    POST請求參數

    request.files:     文件上傳

    request.headers:   請求頭

    request.cookie:     請求中的cookie

  ImmutableMultiDict是類字典的數據結構,與字典的區別是:能夠存在相同的鍵。args和form都是ImmutableMultiDict的對象

  ImmutableMultiDict中數據獲取的方式:dict['uname'] 或 dict.get('uname')。獲取指定key對應的全部值:dict.getlist('uname')

  • Response

  服務器返回給客戶端的數據。response是伴隨request出現的,不能主動出現。由開發者建立

  返回類型:返回字符串、返回模板、返回標籤、返回Response、返回重定向、終止 abort(404)

  Response返回方式:

    1. 直接返回Response對象;return Response("login success") 

    2. 經過 make_response(date,code) 返回。date:返回的數據內容;code:狀態嗎

    3. 返回文本內容,狀態碼。return "登錄成功" 或者:return 404

    4. 返回模版。return render_template('req.html')

  Response響應類型:

    1. 直接的響應請求

    2. 重定向請求:return redirect("/")  或者動態獲取:return redirect(url_for('藍圖名.視圖函數名'))

    3. 終止請求:   abort(400)

    4. 捕獲異常:   @路由名.errorhandler(狀態碼)

 1 @bp.route('/resp/')
 2 def resp():
 3 
 4     # 經過 render_template 返回字符串。響應類型是 str,頁面最終會以字符串的形式返回到前端頁面
 5     # response = render_template('req.html')
 6 
 7     # 經過 make_response 建立一個相應。響應類型是 Flask.wrappers.Response 對象
 8     response = make_response("make_response")
 9 
10     print(type(response))
11     return response
12 
13 
14 @bp.route('/redi/')
15 def redi():
16 
17     # redirect 的第一個參數 是須要跳轉的地址
18     # 相應類型:<class 'werkzeug.wrappers.Response'>
19     # 設置格式:藍圖名.視圖函數
20 
21     response = redirect(url_for('blue.req'))
22     print(type(response))
23     return response
返回類型
 1 from flask import Flask, render_template, request, Response, make_response, redirect, url_for, abort
 2 app = Flask(__name__)
 3 
 4 @app.route('/', methods=["GET", "POST", "PUT", "DELETE"])  # 容許請求的方式 設置methods參數。默認是get
 5 def hello_world():         # 首頁視圖函數
 6     print(request)         # 獲取ruquest請求對象。request屬於flask中的內置對象,全局可調用
 7     print(request.method)  # 獲取request請求對象的請求方式
 8     if request.method == "GET":
 9         print(request.remote_addr)           # 獲取其請求對象遠端的IP
10         print(request.args)                  # args是獲取get的請求參數。打印ImmutableMultiDict([])對象
11         print(request.args.get("username"))  # 獲取get請求中url中的用戶名參數
12         print(request.args.get("hobby"))     # 獲取get請求中url中攜帶的愛好參數
13         print(request.args.getlist("hobby")) # 獲取get請求中url中攜帶的愛好參數列表
14         return render_template('index.html') # 渲染給html頁面
15     elif request.method == "POST":
16         return "據說你是POST"
17     elif request.method == "PUT":
18         return "PUT沒聽過"
19 
20 
21 @app.route("/register/")                     # 實現註冊功能的視圖函數
22 def register():
23     return render_template('register.html')  # 頁面渲染,返回給前端html頁面
24 @app.route("/doregister/", methods=["GET", "POST"])
25 def do_register():
26     print(request.form)                      # form是獲取post請求的參數
27     username = request.form.get("username")  # 獲取post請求的username參數
28     password = request.form.get("password")  # 獲取post請求的password參數
29     print(username, password)                # 打印獲取的參數
30     return "註冊成功"                         # 僞裝 數據存儲成功
31 
32 
33 @app.route("/login/")                        # 實現登錄功能的視圖函數
34 def login():
35     return render_template('login.html')     # 頁面渲染,返回給前端html頁面
36 @app.route("/dologin/", methods=["POST"])
37 def do_login():
38     print(request.form)                      # form是獲取post請求的參數
39     username = request.form.get("username")  # 獲取post請求的username參數
40     password = request.form.get("password")  # 獲取post請求的password參數
41     print(username, password)                # 打印獲取的參數
42     # return '登錄成功'                       # 僞裝 數據讀取、數據校驗
43     # response = Response("login success")          # 返回response信息
44     response = make_response("login fail", 400)     # 返回response信息。返回登錄失敗
45     return response
46 
47 
48 @app.route("/users/")
49 def users():
50     return redirect("/")                       # 重定向到根目錄
51     # return redirect(url_for('do_register'))  # 重定向到do_register視圖函數上。也能夠在html文件中使用實現頁面跳轉
52     # abort(400)                               # 返回響應數字。終止請求
53 
54 if __name__ == '__main__':
55     app.run(debug=True, host="0.0.0.0")
 1 # 終止請求,自動設置模擬異常
 2 @bp.route('/error/404')
 3 def error_404():
 4     # 模擬服務器資源不存在的狀況,若是資源不存在,則告訴瀏覽器 404錯誤
 5     abort(404) 
 6 
 7 @bp.route('/error/500')
 8 def error_500():
 9     # 模擬服務器代碼報錯的狀況,abort以後的代碼不會再被執行
10     abort(500)
11 
12 
13 # 捕獲異常,未拋出的異常不會被捕獲到
14 @bp.errorhandler(404)
15 def error_hander(exception):  # exception獲取錯誤參數 16     print(exception)
17     return '服務器走丟了'
18 
19 @bp.errorhandler(500)
20 def server_error(exception):
21     print(exception)
22     return "服務器開小差了"
 1     <!-- Font Awesome Icons -->
 2     <link rel="stylesheet" href="{{ url_for("static",filename="css/fontawesome-free/css/all.min.css") }}">
 3     <!-- Theme style -->
 4     <link rel="stylesheet" href="{{ url_for("static",filename="css/adminlte.min.css") }}">
 5 
 6 {# static是靜態文件名字,動態獲取靜態文件的路徑,而後和後面的相對路徑拼接上獲取真實路徑   #}
 7 
 8 
 9 
10 <ul>
11     {% for student in student_list %}
12         <li><a href="{{ url_for("student",id=student.id) }}">{{ student.name }}</a></li>
13     {% endfor %}
14 </ul>
15 
16 {# 實現頁面跳轉,idstudent視圖函數的參數 #}


  •  url_for

  url_for 函數⽤於構建指定函數的 URL。它把 路由.函數名. 做爲第一個參數。

  能夠接受任意個關鍵字參數,每一個關鍵字參數對應 URL 中的變量。未知變量將添加到 URL 中做爲查詢參數。

1 @bp.route('/args/<string:name>/<int:age>/')
2 def args(name, age):
3     print(request.args)
4     return 'name: {}, age: {}'.format(name, age)
5 
6 @bp.route('/redi/')
7 def redi():
8       # /args/Tom/19/?a=1&b=2
9     return redirect(url_for('blue.args', name='Tom', age=19, a=1, b=2))
url_for
 1 import random
 2 from flask import Blueprint, render_template
 3 from sqlalchemy import distinct, not_, and_, or_
 4 from app.models import User, db, Grade, Student, Profile
 5 
 6 bp = Blueprint("blue",__name__)
 7 
 8 # 向模版中傳遞參數去渲染。列表類型。
 9 @bp.route("/articles/")
10 def article_list():
11     # 從數據庫中獲取數據,類型是:list。list中的每個數據是一個對象;一個對象對應數據庫中的一行數據
12     # articles = Article.query.with_entities('id', 'title', 'content').all()
13 
14     list_str = ["Tom", "Suan", "Linli", "Bob", "Sufei"]
15     return render_template("article.html", list_str=list_str)
16 
17 # 從路由中獲取參數。字符串類型。
18 @bp.route("/articles/<string:article_id>/")
19 def article_detail(article_id):
20     return article_id
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 <ul>
 9     {% for foo in list_str %}  {#  頁面跳轉URL:http://127.0.0.1:5000/articles/4/?dee=4&abc=566。article_id=foo 實現對參數的傳遞 #}
10         <li><a href="{{ url_for('blue.article_detail', article_id=foo, dee=4, abc=566) }}">{{ foo }}</a>
11         </li>
12     {% endfor %}
13 </ul>
14 </body>
15 </html>

 

模版語言

  模版在程序中主要是呈現給用戶的界面展現的,在MTV中充當T的角色,實現了VT解耦合。

  開發中VT的對應關係是:N:M的關係。一個V能夠調用任意T,一個T能夠被任意V調用。

  Flask中使用Jinja2模版引擎。Jinja2由Flask的做者開發,是一個現代化設計和友好的python模版語言。模仿的是django的模版語言

 優勢

  1. 速度快,被普遍使用

  2. html設計和後端python開發分離

  3. 減小python複雜度

  4. 很是靈活,快速和安全

  5. 提供了控制、繼承等高級功能

 模版處理分爲兩個過程

  1. 加載,在模版中使用視圖函數中傳遞過來的數據

  2. 渲染,在視圖中經過關鍵字參數的形式傳遞參數

 模版代碼包含兩部分

  1. 靜態html

  2. 動態插入的代碼段

 模版語法分類

  1. 變量:模版中的變量,{{ var }}

      視圖傳遞給模版的數據、前面定義出來的數據、變量不存在的話默認忽略

  2. 標籤:模版中的標籤,{% tag %}

      控制邏輯、使用外部表達式、建立變量、宏定義

  • 變量 {{ var }}     
 1 from flask import Flask, render_template
 2 
 3 app = Flask(__name__)
 4 
 5 @app.route('/') # 傳入參數給html,模版渲染
 6 def hello_world():
 7     return render_template('FlaskTemplate.html',msg='而後你沒有帶傘')
 8 
 9 if __name__ == '__main__':
10     app.run(debug=True)
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Index</title>
 6 </head>
 7 <body>
 8 
 9 <h1>據說今天有雷陣雨</h1>
10 <h3>{{ msg }}</h3>
11 
12 </body>
13 </html>
  • 結構標籤 {% tag %}

  1. 父類中結構標籤 block

    {% block xxx %}    block :塊操做、坑。父模板挖坑子模板填坑。

    {% endblock %}    endblock:挖坑繼承體現的是化整爲零的操做

  2. 子類中結構標籤 extends:

    {% extends 'xxx' %}   繼承、擴展。子模板能夠填充父類中的塊坑。沒有填充的塊會自動優化掉

    {% super() %}           繼承後保存父塊中的內容

 1 {# base文件中挖的坑信息 #}
 2 <!DOCTYPE html>     
 3 <html lang="en">
 4 <head>
 5     <meta charset="UTF-8">
 6     <title>{{ title }}</title>
 7 </head>
 8 <body>
 9 {# 頭部信息 挖的坑#}
10 {% block header %}
11 {% endblock %}
12 
13 {# 輪播信息 挖的坑#}
14 {% block banner %}
15 {% endblock %}
16 
17 {# 內容信息 挖的坑#}
18 {% block content %}
19 {% endblock %}
20 
21 {# 尾部信息 挖的坑#}
22 {% block footer %}
23 {% endblock %}
24 </body>
25 </html>
1 {# home.html模板 繼承自 base.html模板 #}
2 {% extends 'base.html' %}
3 
4 {# 對繼承的header進行數據填充 #}
5 {% block header %}
6     <h1>子類模版繼承父類模版的坑,填坑</h1>
7 {% endblock %}
 1 {# home1.html模版 繼承自 home.html模版。home模版中的信息,home1都會繼承過來 #}
 2 {% extends 'home.html' %}
 3 
 4 {# 若是孫類中重新賦值新的信息給子類中的坑,子類中的信息會被覆蓋掉 #}
 5 {% block header %}
 6     {# 禁止覆蓋其父類中的信息 #}
 7     {{ super }}
 8     <h2>子類中的信息,會被孫類覆蓋掉</h2>
 9 {% endblock %}
10 {# 孫類中繼續挖坑,在其子類中還能夠繼續填坑 #}
11 {% block content %}
12     {% block left %}
13     {% endblock %}
14     
15     {% block right %}
16     {% endblock %}
17 {% endblock %}

   block:塊,坑。塊沒有填充,會被自動優化掉,不會報錯

    首次出現表明定義一個塊表明界面的一種規劃;

    二次出現表明對既有塊填充;塊中能夠繼續規劃新的塊

    三次出現表明對既有塊的填充,會覆蓋上一次的內容,不想被覆蓋,使用{{ super() }}。

   extends:繼承,模板的繼承。block + extends:化整爲零

  3. 包含 include: 

    {% include %}   include 包含,將其餘html文件的內容包含進來,體現的是 由零到一 的概念。效率沒有上面的高

1 {# header.html #}
2 <h2>這是一個頭</h2>
1 {# content.html #}
2 <h2>這是一個內容</h2>
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>首頁</title>
 6 </head>
 7 <body>
 8 {% include 'home.html' %}  
 9 {% include 'content.html' %}
10 </body>
11 </html>

  4. 宏定義 marco:

    {% marco hello(name) %}

       {{ name }}

    {% endmarco %}    marco 宏定義,能夠在模版中定義函數,在其餘地方調用

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>首頁</title>
 6 </head>
 7 <body>
 8 {# 編寫宏 #}
 9 {% macro hello(name) %}
10     <h1>你好{{ name }}這是一個宏標籤</h1>
11 {% endmacro %}
12 {# 調用宏 #}
13 {{ hello('小明') }}
14 {{ hello('小紅') }}
15 </body>
16 </html>

    {% from 'xxx' import xxx %}  宏定義可導入

 1 {# haha.html文件 #}
 2 {% macro haha() %}
 3     <h1>哈哈大笑</h1>
 4 {% endmacro %}
 5 
 6 
 7 
 8 
 9 <!DOCTYPE html>
10 <html lang="en">
11 <head>
12     <meta charset="UTF-8">
13     <title>首頁</title>
14 </head>
15 <body>
16 {# 導入宏 #}
17 {% from 'haha.html' import haha %}
18 {# 使用宏 #}
19 {{ haha() }}
20 </body>
21 </html>
  • 功能標籤

  1. 循環控制  {% for item in items %}......{% endfor %}

   循環器loop

    loop.first      選擇第一個數據
    loop.last      選擇最後一個數據
    loop.index   帶序號顯示數據
    loop.revindex  反轉序號顯示
    loop.index0    從0序號開始顯示

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>首頁</title>
 6 </head>
 7 <body>
 8 {% for habby in habbies %}
 9     {# 帶序號的顯示愛好信息   #}
10     <li>{{ loop.index }}{{ habby }}</li>
11 {% endfor %}
12 </body>
13 </html>

  2. 邏輯控制  {% if exp %}...{% elif exp %}...{% else exp %}...{% endif %}

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>首頁</title>
 6 </head>
 7 <body>
 8 {% for habby in habbies %}
 9     {% if loop.first %}
10         <li style="color:red">{{ habby }}</li>
11     {% elif %}
12         <li style="color: green">{{ habby }}</li>
13     {% else %}
14         <li>{{ habby }}</li>
15     {% endif %}
16 {% endfor %}
17 </body>
18 </html>
  • 過濾器  {{ var|過濾器|過濾器 }}

  過濾器名稱:capitalize;lower;upper;title;trim;reverse;format;striptags 渲染以前,將值中標籤去掉 

  過濾器名稱:sort;sum;length;first;last;default;safe 將返回數據中的標籤渲染出來,確保數據不是js破壞代碼再用

1 {% for habby in habbies %}
2     {% if loop.first %}
3         <li style="color:red">{{ habby }}</li>
4     {% elif %}
5         <li style="color: green">{{ habby|reverse }}</li>
6     {% else %}
7         <li>{{ habby|upper }}</li>
8     {% endif %}
9 {% endfor %}

數據模型

   Flask 默認沒有提供任何數據庫操做的API,可選擇任意合適本身項目的數據庫:可用原生數據庫語、也可用ORM實現功能(SQLAlchemy 或 MongoEngine)

   ORM(Object Relational Mapping) 對象關係映射。將數據庫轉爲面向對象的操做,經過操做對象就可實現對數據的CRUD。如業務模型和數據庫DB之間的翻譯機

  • ORM 優勢:

    開發效率高,設計靈活能夠輕鬆完成複雜查詢

    移植性高,能夠對接多種數據庫,實現了防SQL注入

    易於理解,便於維護(將數據轉換爲面向對象編程)

  • ORM 缺點:

    執行效率低,由於須要將對象的操做轉換爲數據庫的SQL。對於複雜操做可能沒有支持

  • 原生SQL缺點:

    代碼利用率低、條件複雜代碼語句越長、有不少類似的語句。

    一些SQL是在業務邏輯中拼出來的,若修改SQL須要瞭解業務邏輯,

    直接寫SQL容易忽視SQL問題(SQL注入問題)


  •  安裝

    安裝 flask-sqlalchemy:pip install flask-sqlalchemy 

    安裝 pymysql驅動  :pip install pymysql

  • 數據類型和操做

   常見字段

    Integer 整型數字  SmallInteger 小型整數  BigInteger 大型整數  Float 浮點類型  Numeric 數字型  

    String 字符串  Text 文本  Unicode 編碼  Unicode Text 編碼文本  Boolean 布爾  

    Date 時間  Time 時間  DateTime 時間  Interval 二進制  LargeBinary 二進制

   常見約束 

      primary_key 主鍵  autoincrement 自增  unique 惟一  index 索引,常差字段加索引

    nullable 是否爲空  default 默認值  ForeignKey() 外鍵,用來約束級聯數據(db.Column( db.Integer, db.ForeignKey(xxx.id) ))

   提交數據

      在事務處理中,對象(數據)插入、修改、刪除是基於查詢的

    db.session.add(object)  把對象(數據)添加到數據庫中

    db.session.add_all(list_obj)把一組對象添加到數據庫中

    db.session.commit()     將要新添加的數據進行提交

      db.session.delete()     對查到的對象(數據)進行刪除

 1 import random
 2 from flask import Flask, render_template
 3 from flask_sqlalchemy import SQLAlchemy
 4 
 5 app = Flask(__name__)
 6 # 配置鏈接mysql數據庫的指定信息。dialect+driver://username:password@host:port/database
 7 app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:guoyapeng@localhost:3306/FlaskModel'
 8 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False              # 設False爲更好的兼容性,禁止對象追蹤修改
 9 db = SQLAlchemy(app)
10 
11 
12 # 建立班級表
13 class Grade(db.Model):                                              # 主表
14     id = db.Column(db.Integer,primary_key=True,autoincrement=True)  # id字段:整型、主鍵、自增
15     name = db.Column(db.String(32),unique=True,nullable=False)      # name字段:字符串型、惟1、不可爲空
16 # 建立學生表
17 class Student(db.Model):                                            # 從表
18     id = db.Column(db.Integer,primary_key=True,autoincrement=True)  # 學生id:  整型,主鍵,自增
19     name = db.Column(db.String(32),nullable=False)                  # 學生姓名:整型,字符串,不爲空
20     grade = db.Column(db.Integer,db.ForeignKey(Grade.id))           # 學生班級:整型,外鍵:Grade表中
1 # 新建數據庫表的url
2 @app.route('/create/')
3 def create():
4     db.create_all()                                                 # 建立數據庫
5     return '數據庫表建立成功'
 1 # 添加C 班級數據信息
 2 @app.route('/addgrade/')
 3 def add_grade():
 4     grade = Grade()
 5     grade.name = 'python%d' % random.randrange(1000)
 6 
 7     db.session.add(grade)
 8     db.session.commit()
 9     return '添加成功'
10 # 添加C 學生數據信息
11 @app.route("/addstudent/")
12 def add_student():
13     student = Student()
14     student.name = "Tom%d" % random.randrange(10000)
15 
16     grade_list = Grade.query.all()
17     grade = grade_list[random.randrange(len(grade_list))]
18     student.grade = grade.id
19 
20     db.session.add(student)
21     db.session.commit()
22     return "添加成功"
 1 # 查詢R 班級列表信息
 2 @app.route('/grades/')
 3 def grades():
 4     grade_list = Grade.query.all()
 5     return render_template('GradeLIst.html',grade_list=grade_list)
 6 # 查詢R 學生列表信息
 7 @app.route('/students/')
 8 def students():
 9     student_list = Student.query.all()
10     return render_template('StudentList.html',student_list=student_list)
 1 # 查詢單個班級信息,並顯示本班全部的學生。路由是:http://127.0.0.1:5000/grade/2/
 2 @app.route('/grade/<int:id>/')  
 3 def grade(id):
 4     grades = Grade.query.filter(Grade.id.__eq__(id)).all() # 查詢id等於指定參數id的信息,加.all()以列表形式獲取全部數據
 5     # grades = Grade.query.filter(Grade.id == id)            同上方法。結果是:sql語句。類型是:basequery對象
 6     grade = grades[0]                        # 獲取列表中的第一個班級元素
 7     student_list = Student.query.filter(Student.grade == id).all()
 8     return render_template('Grade.html',grade=grade,student_list=student_list)
 9 # 查詢單個學生的信息。路由是:http://127.0.0.1:5000/student/2/
10 @app.route('/student/<int:id>/')
11 def student(id):
12     student = Student.query.get(id)                        # 獲取指定id的學生
13     return render_template('student.html',student=student)
14 
15 if __name__ == '__main__':
16     app.run()
 1 # 數據庫D 對數據刪除
 2 @bp.route("/delete/")
 3 def delete():
 4     #刪除時,必須先查詢到數據,再對對象進行刪除
 5     user = User.query.get(1)
 6     # 經過 delete 刪除一個數據
 7     db.session.delete(user)
 8     # 對象刪除完後,執行commit向數據庫提交更新
 9     db.session.commit()
10     return "update ok"
  • 數據庫鏈接

  Python語言中的ORM(SQLAlchemy)。下載安裝包針對於Flask的支持:pip install flask-sqlalchemy

  sqlite數據庫是一個輕量級的數據庫,適合寫案例、微小項目.如:博客、我的網站、手機應用開發(手機內置數據庫)

 1 from flask import Flask, render_template
 2 from flask_sqlalchemy import SQLAlchemy
 3 
 4 app = Flask(__name__)
 5 
 6 # 配置鏈接sqlite數據庫的指定信息。
 7 app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///hello.sqlite'  
 8 # 設False爲更好的兼容性,禁止對象追蹤修改
 9 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False              
10 # SQLite數據庫鏈接不須要額外驅動,也不須要用戶名和密碼
11 db = SQLAlchemy(app)                                              
12 
13 
14 # 配置鏈接mysql數據庫的指定信息。dialect+driver://username:password@host:port/database
15 app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:guoyapeng@localhost:3306/FlaskModel'
16 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False              
17 db = SQLAlchemy(app)
18 
19 
20 if __name__ == '__main__':
21     app.run()
  • 數據庫操做

     db.create_all():建立數據庫表  

     db.drop_all():刪除數據庫表 

 1 @bp.route("/create_db/")
 2 def create_db():
 3     """
 4     建立表
 5     """
 6     from app.models import db
 7     db.create_all()
 8     return "db create"
 9 @bp.route("/drop_db/")
10 def drop_db():
11     """
12     刪除表
13     """
14     from app.models import db
15     db.drop_all()
16     return "db drop"

增刪改查

  • manag.py
1 from flask_script import Manager
2 from app import create_app
3 
4 app = create_app()
5 manager = Manager(app)
6 
7 if __name__ == '__main__':
8     manager.run()
  • app/__init__.py
 1 import os
 2 from flask import Flask
 3 from app import views
 4 from app.models import db
 5 
 6 def create_app():
 7 
 8     app = Flask(__name__)
 9 
10     # sqlite3 數據庫文件地址
11     db_file = os.path.join(app.root_path,"sqlite.db")
12     # 指定數據庫的 URI
13     app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + db_file
14 
15     # 關閉 SQLAchemy 底層對象監聽功能
16     app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
17     # 打印sql語句設置
18     app.config["SQLALCHEMY_ECHO"] = True
19 
20     # 使用 flask app 初始化 SQLAchemy
21     db.init_app(app=app)
22 
23     app.register_blueprint(views.bp)
24 
25     return app
  • app/models.py
 1 """
 2 flask 使用 ORM 的步驟
 3 1。 指定數據庫鏈接。並創建SQLAlchemy對象
 4     app.config["SQLALCHEMY_DATABASE_URI"]
 5 2。 定義模型類
 6 3。 經過 ORM 將模型類 轉換成 數據庫中的表
 7 4。 經過模型類進行curd
 8 """
 9 import datetime
10 from flask_sqlalchemy import SQLAlchemy
11 
12 db = SQLAlchemy()  # 實例化SQLAlchemy
13 
14 class User(db.Model):
15     __tablename__ = "users"
16 
17     id = db.Column(db.Integer,primary_key=True,autoincrement=True)
18     name = db.Column(db.String(16),nullable=False)
19     age = db.Column(db.Integer,default=18)
20 
21     def __repr__(self):     # 自定義打印效果
22         return "<User,id:{},name:{},age:{}>".format(self.id, self.name, self.age)
23 
24     """
25     繼承 db.Model 說明此類是一個 SQLAlchemy 的模型類
26     db.Column 定義模型類屬性對應的數據庫關係
27 
28     默認的表名規則:
29         模型名的小寫,User -> user
30         若是是駝峯型,UserModel -> user_model
31         能夠經過 __tablename__ 自定義表名
32 
33     db。Colume 定義模型類屬性對應的數據庫表字段關係
34         默認的字段名爲屬性名
35         須要爲每一個屬性指定數據庫中使用的類型
36             db.Integer 整型
37             db.String(size) 字符串,size爲最大長度
38             db.Text 長文本
39             db.DataTime 時間日期,python datetime對象
40             db.Boolean 布爾類型
41             
42         primary_key : 是否爲主鍵
43         nullable : 是否爲空
44         unique : 惟一約束
45         index : 索引
46         autoincrement : 自增(默認爲auto)
47     """
  • app/views.py
 1 """
 2     User.query
 3         query 是一個查詢接口,BaseQuery的對象。不真正執行SQL
 4             .all()   得到全部記錄,真正執行 SQL 查詢數據
 5             .first() 獲取第一條數據,真正執行 SQL 查詢數據
 6             .get(pk) 根據主鍵查詢
 7             
 8             .filter()     where 條件。支持更豐富的查詢條件
 9                           filter(User.age > 18)
10                           filter(User.age == 18)
11             .filter_by()  where 條件。只能經過關鍵字賦值
12                           filter_by(name=XXX,age=XXX)   
13     :return: 
14 """
調用的方法介紹
1 import random
2 from flask import Blueprint
3 from sqlalchemy import distinct, not_, and_, or_
4 from app.models import User, db, Grade, Student, Profile
5 
6 bp = Blueprint("blue",__name__)
 1 """-----------------建立庫 刪除庫-----------------------"""
 2 @bp.route("/create_db/")
 3 def create_db():
 4     """
 5     建立表
 6     """
 7     from app.models import db
 8     db.create_all()
 9     return "db create"
10 @bp.route("/drop_db/")
11 def drop_db():
12     """
13     刪除表
14     """
15     from app.models import db
16     db.drop_all()
17     return "db drop"
 1 """-------------------- 增 -------------------- """
 2 # 數據庫C操做。建立數據
 3 @bp.route("/create/")
 4 def create():
 5     user = User()
 6     user.name = "老王"
 7     user.age = 88
 8 
 9     db.session.add(user)
10     db.session.commit()
11     return "create"
12 
13 @bp.route("/creates/")
14 def creates():
15     users = []
16     for i in range(10):
17         name = "jack-{}".format(i)
18         age = random.randint(18,55)
19         u = User(name=name,age=age)
20         users.append(u)
21     # add_all 接收一組數據,實現批量新增數據
22     db.session.add_all(users)
23     db.session.commit()
24     return "creates"
 1 """--------------------- 改 --------------------"""
 2 # 數據庫U。對數據更新
 3 @bp.route("/update/")
 4 def update():
 5     #更新時,必須先查詢到數據,再對對象進行更新
 6     user = User.query.get(1)
 7     user.age = 17
 8 
 9     # 對象修改完後,執行commit向數據庫提交更新
10     db.session.commit()
11     return "update ok"
 1 """--------------------- 刪 ------------------"""
 2 # 數據庫D。對數據刪除
 3 @bp.route("/delete/")
 4 def delete():
 5     #刪除時,必須先查詢到數據,再對對象進行刪除
 6     user = User.query.get(1)
 7     # 經過 delete 刪除一個數據
 8     db.session.delete(user)
 9 
10     # 對象刪除完後,執行commit向數據庫提交更新
11     db.session.commit()
12     return "update ok"
 1 """--------------------- 查 ---------------------"""
 2 # 數據庫R。查詢數據
 3 @bp.route("/read/")
 4 def read():
 5     # 根據主鍵獲取 user 對象。若是主鍵不存在,則返回 None
 6     user = User.query.get(2)  # 查詢id爲3的人員信息
 7     user = User.query.first() # 查詢第一我的員信息
 8 
 9     # filter_by 中的關鍵字參數的參數名爲 要查詢模型的屬性名,即數據庫字段
10     # 過濾查詢,打印的是mysql語句。類型:<class 'flask_sqlalchemy.BaseQuery'>實例
11     user = User.query.filter_by(name="jack-0").first() # .first() 獲取對象中的第一個數據信心
12     user = User.query.filter_by(age=19,name="jack").all() # .all()獲取的是一組數據,類型是list。值是User模型對象列表
13     user = User.query.filter(User.age == 41).all() # 另一種寫法
14 
15     # 按需查詢 年齡爲41歲人員的名字。with_entities 按需查詢字段
16     user = User.query.with_entities(User.name).filter_by(age=41).all()
17 
18     # distinct 按年齡字段去重
19     user = User.query.with_entities(distinct(User.age)).all()
20 
21 
22     # filter  中的關鍵字參數的參數名爲 要查詢模型的屬性名,即數據庫字段
23     # 條件查詢。查詢年齡字段小於39歲的人員信息
24     user = User.query.filter(User.age <= 39).all()
25 
26     # like 'jack%'
27     users = User.query.filter(User.name.startswith('jack')).all()
28     # like '%jack'
29     users = User.query.filter(User.name.endswith('jack')).all()
30     # like '%jack%'
31     users = User.query.filter(User.name.contains('jack')).all()
32 
33     # 指定範圍內。age in [19, 38, 42]
34     users = User.query.filter(User.age.in_([19, 38, 42])).all()
35 
36     # 排序
37     users = User.query.order_by('age')
38     users = User.query.order_by(User.age.desc())
39 
40     # not 非
41     users = User.query.filter(User.age != 19).all()
42     users = User.query.filter(not_(User.age == 19)).all()
43     # and 與
44     users = User.query.filter(and_(User.age == 19, User.name == 'jack-0')).all()
45     users = User.query.filter(User.age == 19, User.name == 'jack-0').all()
46     users = User.query.filter_by(age=19, name='jack-0')
47     # or 或
48     users = User.query.filter(or_(User.age == 19, User.age == 42)).all()
49 
50     print(users)
51     return 'read'

模型關係

  • app/models.py 

  從表中,定義外鍵字段;主表中,定義關係。(誰聲明外鍵誰是從表)

 1 # 1:n  Grade:Student
 2 class Grade(db.Model):
 3     __tablename__ = "grades"
 4 
 5     g_id = db.Column(db.Integer,primary_key=True) # 主鍵
 6 
 7     created_at = db.Column(db.DateTime,default=datetime.datetime.now())
 8 
 9     # 經過設置onupdate 在對象更新時,自動更新updated_at。能夠幫助統計天天註冊人數
10 
11     updated_at = db.Column(db.DateTime,default=datetime.datetime.now(),onupdate=datetime.datetime.now())
12 
13     g_name = db.Column(db.String(16),unique=True,nullable=False)
14 
15     # 注意⚠️:db.relationship() 定義一個模型關係(Colume是關係到數據庫中)。提供了可讓Grade對象 g 經過g.students的方式訪問N(多)的一方數據的便利性
16     # 第一參數:關係N方模型的類名;第二參數backref: 反響關係引用,反向在Student方新增grade字段(屬性),方便Student對象s.grade訪問1方字段;第三參數lazy:加載關聯關係數據的時機
17     #   lazy = Ture/"select"時 會發送兩條sql語句,一條查 one 的一方;一條查 many的一方
18     #   lazy = False/"joined" 時 會發送一條sql語句,經過LEFT JOIN 的方式查詢 one 一方 和 many 一方數據
19     #   lazy = "dynamic" 時 會發送一條 sql語句,只查詢 one 一方的數據,many 一方的關聯屬性是一條 Query 對象,
20     #          不會真實執行查詢,在須要時,調用students.all() 真正去數據庫中查詢數據
21     students = db.relationship("Student",backref="grade",lazy=True)
22 
23 
24 class Student(db.Model):
25     __tablename__ = "students"
26 
27     s_id = db.Column(db.Integer, primary_key=True)  # 主鍵
28 
29     created_at = db.Column(db.DateTime, default=datetime.datetime.now())
30 
31     # 經過設置onupdate 在對象更新時,自動更新updated_at。能夠幫助統計天天註冊人數
32     updated_at = db.Column(db.DateTime, default=datetime.datetime.now(), onupdate=datetime.datetime.now())
33 
34     s_name = db.Column(db.String(16),unique=False)
35 
36     s_age = db.Column(db.Integer,default=18,nullable=False)
37 
38     # db.ForeignKey() 用於定義外鍵,參數:主標的表名.主鍵名
39     grade_id = db.Column(db.Integer,db.ForeignKey("grades.g_id"))
40 
41     # one to one 的聲明方式和 one to many 幾乎一致,區別在於:
42     # 不使用 lazy。使用 uselist = Flase 來模擬只返回一條數據
43     profile = db.relationship("Profile",backref= "student",uselist=False)
44 
45 
46 # 1:1  Student:Profile
47 class Profile(db.Model):
48     __tablename__ = "profiles"
49 
50     id = db.Column(db.Integer,primary_key=True) # 主鍵
51 
52     created_at = db.Column(db.DateTime, default=datetime.datetime.now())
53 
54     # 經過設置onupdate 在對象更新時,自動更新updated_at。能夠幫助統計天天註冊人數
55     updated_at = db.Column(db.DateTime, default=datetime.datetime.now(), onupdate=datetime.datetime.now())
56 
57     phone = db.Column(db.String(16),unique=True,nullable=False)
58 
59     student_id = db.Column(db.Integer,db.ForeignKey("students.id"))
  • 1:1
  • app/views/py
 1 @bp.route('/o2o-create/')
 2 def o2o_create():
 3     # p = Profile(phone='13888888881')
 4     # db.session.add(p)
 5     # db.session.commit()
 6     p = Profile.query.filter_by(phone='13888888888').first()
 7 
 8     s = Student.query.first()
 9     s.profile = p   # s.profile_id = p.id
10 
11     db.session.commit()
12     return 'o2o_create'
13 
14 
15 @bp.route('/o2o-read/')
16 def o2o_read():
17     s = Student.query.filter_by(name='tom-0').first()
18     print(s.profile.phone)
19 
20     p = Profile.query.filter_by(phone='13888888888').first()
21     print(p.student.name) # 經過Profile模型的對象p 去獲取Student模型中的name屬性值 22 
23     return 'o2o_read'
  • 1:N
  • app/views.py
 1 @bp.route("/o2m_create/")
 2 def o2m_create():
 3     """
 4     1:n 新增操做
 5     :return:
 6     """
 7     python1901 = Grade(g_name='python-1901')
 8     python1902 = Grade(g_name='python-1902')
 9     python1903 = Grade(g_name='python-1903')
10 
11     grades = [python1901,python1902,python1903]
12     db.session.add_all(grades)
13     db.session.commit()
14 
15     students = []
16     for i in range(30):
17         name = 'tom-{}'.format(i)
18         age = 18 + random.randint(0,5)
19 
20         s = Student(s_name=name,s_age=age)
21 
22         # ⚠️經過反向引用的屬性賦值,也能夠只經過 grade_id 進行賦值、
23         s.grade = random.choice(grades) # 隨機選取一個班級對象。將班級對象 g 賦值給 s.grade。本質上至關於:s.grade_id = g.id 24         students.append(s)
25 
26         db.session.add_all(students)
27         db.session.commit()
28     return "o2m create ok"
29 
30 
31 @bp.route("/o2m_read/")
32 def o2m_read():
33     # 經過班級查詢獲取班級下的全部學生
34     g = Grade.query.first()
35     # 當lazy= "dynamic" 時,g.students 是一個 Query 對象,只有經過 g.students.all() 纔會發送 SQL 語句,執行查詢
36     # print(type(g.students))
37     # print(g.students.all())
38 
39     # 經過Student對象s獲取Grade模型中的班級名字字段
40     s = Student.query.first()
41     print(s.grade.g_name)
42     return "o2m_read ok"
43 
44 @bp.route('/o2m_update/')
45 def o2m_update():
46     tom_4 = Student.query.filter_by(s_name='tom-4').first()
47     python_1902 = Grade.query.filter_by(g_name="python-1902").first()
48     # 更改學生班級信息。至關於:tom_4.grade_id = python_1902.id
49     tom_4.grade = python_1902
50     db.session.commit()
51     return "02m_update ok"
52 
53 @bp.route('/o2m_delete/')
54 def o2m_delete():
55     # 笨辦法
56     # python_1902 = Grade.query.filter_by(name='python-1902').first()
57     # tom_4 = Student.query.filter_by(name="tom-4").first()
58     #
59     # python_1902.students.remove(tom_4) 添加時: python1902.student.append(s)
60     # db.session.commit()
61 
62     python_1901 = Grade.query.filter_by(name="python-1901").first()
63     db.session.delete(python_1901)
64     db.session.commit()
65     return "o2m_delete ok"
  •  N:M 
 1 # 笨辦法。僞代碼
 2 Student(db.Model)
 3     id, name
 4 Group (db.Model)
 5     id, name,
 6 StudentGroup(db.Model)
 7     id, student_id(fk,student.id),  group_id(fk,group.id)
 8     
 9 
10 s = Student(name="Tom")
11 db.session.add(s)
12 db.session.commit()
13 
14 g = Group(name="Html")
15 db.session.add(g)
16 db.session.commit()
17 
18 
19 sg = StudentGroup()
20 sg.student_id = s.id 
21 sg.group_id = g.id
22 db.session.add(sg)
23 db.session.commit()
普通方法
 1 # 多對多(普通方式)
 2 class User(db.Model):
 3     id = db.Column(db.Integer,primary_key=True,autoincrement=True)
 4     name = db.Column(db.String(32))
 5     age = db.Column(db.Integer,default=18)
 6 
 7 class Movie(db.Model):
 8     id = db.Column(db.Integer,primary_key=True,autoincrement=True)
 9     name = db.Column(db.String(32))
10 
11 class Collection(db.Model):
12     id = db.Column(db.Integer,primary_key=True,autoincrement=True)
13     u_id = db.Column(db.Integer,db.ForeignKey(User.id))
14     m_id = db.Column(db.Integer,db.ForeignKey(Movie.id))
15     
16     # 購物車添加
17     @blue.route('/getcollection/')
18     def getcollection():
19           u_id = int(request.args.get('u_id'))
20           m_id = int(request.args.get('m_id'))
21           c = Collection.query.filter(Collection.u_id == u_id).filter_by(m_id = m_id)
22 
23           if c.count() > 0:
24               print(c.first().u_id,c.first().m_id)
25               # print(c)
26               # print(type(c))
27               # print('i am if')
28               return '已經添加到了購物車中'
29           else:
30               c1 = Collection()
31               c1.u_id = u_id
32               c1.m_id = m_id
33               db.session.add(c1)
34               db.session.commit()
35               return 'ok'
普通方式
  • app/models.py
 1 class Student(db.Model):
 2     __tablename__ = "students"
 3 
 4     s_id = db.Column(db.Integer, primary_key=True)  # 主鍵
 5 
 6     created_at = db.Column(db.DateTime, default=datetime.datetime.now())
 7     # 經過設置onupdate 在對象更新時,自動更新updated_at。能夠幫助統計天天註冊人數
 8     updated_at = db.Column(db.DateTime, default=datetime.datetime.now(), onupdate=datetime.datetime.now())
 9 
10     s_name = db.Column(db.String(16),unique=False)
11 
12     s_age = db.Column(db.Integer,default=18,nullable=False)
13 
14     # db.ForeignKey() 用於定義外鍵,參數:主標的表名.主鍵名
15     grade_id = db.Column(db.Integer,db.ForeignKey("grades.g_id"))
16 
17     # one to one 的聲明方式和 one to many 幾乎一致,區別在於:
18     # 不使用 lazy。使用 uselist = Flase 來模擬只返回一條數據
19     profile = db.relationship("Profile",backref= "student",uselist=False)
20 
21     # many to many 的關係定義,本質是雙向的一對多關係
22     # secondary 指定多對多關係中的關係表
23     groups = db.relationship('Group', secondary='student_groups',
24                              backref=db.backref('students', lazy='dynamic'), lazy='dynamic')
25 
26 """ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"""
27 
28 # n:m   Group:Student
29 class Group(db.Model):
30     __tablename__ = 'groups'
31 
32     id = db.Column(db.Integer, primary_key=True)  # 主鍵
33 
34     created_at = db.Column(db.DateTime, default=datetime.datetime.now())
35     updated_at = db.Column(db.DateTime, default=datetime.datetime.now(), onupdate=datetime.datetime.now())
36 
37     name = db.Column(db.String(32), unique=True, nullable=False)
38 
39 # db.Table() 第一個參數:表名;其餘參數:字段定義
40 student_groups = db.Table('student_groups',
41                           db.Column('id', db.Integer, primary_key=True),
42                           db.Column('student_id', db.Integer, db.ForeignKey('students.id')),
43                           db.Column('group_id', db.Integer, db.ForeignKey('groups.id'))
44                           )
  • app/views.py 
 1 @bp.route('/m2m-init/')
 2 def m2m_init():
 3     g1 = Group(name='python')
 4     g2 = Group(name='html')
 5     g3 = Group(name='golang')
 6 
 7     db.session.add_all([g1, g2, g3])
 8     db.session.commit()
 9 
10     return 'm2m_init ok'
11 
12 
13 @bp.route('/m2m-create/')
14 def m2m_create():
15     # 獲取 組模型的對象
16     python = Group.query.filter_by(name='python').first()
17     html = Group.query.filter_by(name='html').first()
18 
19     # 根據學生主鍵 獲取學生對象
20     tom_0 = Student.query.get(1)
21     tom_1 = Student.query.get(2)
22 
23     # 根據 組對象中的students字段添加學生tom_0
24     python.students.append(tom_0)
25 
26     # 根據 學生對象的groups字段添加組html
27     tom_1.groups.append(html)
28 
29     db.session.commit()
30     return 'm2m_create ok'
31 
32 
33 @bp.route('/m2m-delete/')
34 def m2m_delete():
35     python = Group.query.filter_by(name='python').first()
36     html = Group.query.filter_by(name='html').first()
37 
38     tom_0 = Student.query.get(1)
39     tom_1 = Student.query.get(2)
40 
41     # 刪除一個不屬於 student 對象的 group 會報錯
42     # tom_0.groups.remove(python)
43 
44     # 清空 html 組內的全部學生
45     html.students = []
46 
47     db.session.commit()
48     return 'm2m_delete ok'

 

數據模型 增刪封裝

  • app/models.py
 1 import datetime
 2 from flask_sqlalchemy import SQLAlchemy
 3 # 實例化SQLAlchemy
 4 db = SQLAlchemy()
 5 
 6 class ModelMixin():
 7     """
 8     Mixin 是一種多繼承的模式。主要爲子類增長擴展功能
 9     """
10 
11     @classmethod
12     def save_all(cls,objs):
13         """
14         定義一個類方法(不須要實例化類就能夠被類自己調用)cls 表明當前類
15         對一組數據進行提交,成功返回True;失敗返回Flask,並數據回滾
16      僞代碼:
17         users = [user, user, user]
18         try:
19             db.session.add_all(users)
20             db.session.commit()
21         except Exception as e:
22             db.session.rollback()
23         User.save_all(users)
24         :param objs:
25         :return:
26         """
27         try:
28             db.session.add_all(objs) # 一次性對一組數據進行存儲提交
29             db.session.commit()
30         except Exception as e:
31             db.session.rollback()    # 沒有存儲成功,進行回滾操做
32             return False
33 
34 
35     def save(self):
36         """
37         定義一個類(必須實例化類以後才能被調用)。self 表明當前類的實例
38         對一組數據進行提交,正確返回True;錯誤返回Flask,並數據回滾
39      僞代碼:
40         user = User(name='jack', age=55)
41         try:
42             db.session.add(user)
43             db.session.commit()
44         except Exception as e:
45             db.session.rollback()
46         user.save()
47         :return:
48         """
49         try:
50             db.session.add(self)
51             db.session.commit()
52             return True
53         except Exception as e:
54             db.session.rollback()
55             return False
56 
57     def delete(self):
58 
59         try:
60             db.session.delete(self) # 刪除操做 61             db.session.commit()
62             return True
63         except Exception as e:
64             db.session.rollback()
65             return False
66 
67 
68 class User(ModelMixin,db.Model):
69     __tablename__ = "users"
70 
71     id = db.Column(db.Integer,primary_key=True,autoincrement=True)
72     name = db.Column(db.String(16),nullable=False)
73     age = db.Column(db.Integer,default=18)
74 
75     def __repr__(self):     # 自定義打印效果
76         return "<User,id:{},name:{},age:{}>".format(self.id, self.name, self.age)
  • app/views.py
 1 import random
 2 from flask import Blueprint, render_template
 3 from sqlalchemy import distinct, not_, and_, or_
 4 from app.models import db, Grade, Student, Profile
 5 from app.models import User
 6 
 7 bp = Blueprint('blue', __name__)
 8 
 9 # 增添
10 @bp.route('/create/')
11 def create():
12     users = []
13     for i in range(10):
14         name = 'tom-{}'.format(i)
15         age = random.randint(18, 88)
16         u = User(name=name, age=age)
17         users.append(u)
18 
19     User.save_all(users)
20     return 'create ok!'
21 
22 # 刪除
23 @bp.route('/delete/')
24 def delete():
25     # 刪除時,必須先查詢到數據,在對對象進行刪除
26     user = User.query.get(13)
27     user.delete()
28 
29     return 'delete'
相關文章
相關標籤/搜索