Flask 輕量級框架 WEB 框架
AJAX 在web中完成異步請求和響應
Django 重量級WEB框架javascript
Python Webcss
1.靜態網頁 和 動態網頁
1.靜態網頁 :沒法與服務器作動態交互的網頁
2.動態網頁 :容許與服務器作動態加護的
2.WEB 與 服務器
1.WEB : 網頁(HTML,CSS,JS)
2.服務器
可以給用戶提供服務的機器就能夠稱爲 服務器
1.硬件 與 軟件
硬件 :一臺主機
軟件 :一個可以接受用戶請求並給出響應的程序
1.APACHE
2.TOMCAT
3.IIS(Internet Information Service)
4.Nginx
2.做用
1.存儲WEB上的信息
2.可以處理用戶的請求(request)並給出響應(response)
3.執行服務器端程序
4.具有必定的安全功能
3.框架
1.什麼是框架
框架是一個爲了解決開放性問題而存在一種程序結構。
框架自己提供了一些最基本的功能。
咱們只須要在基礎功能上搭建本身的操做就能夠了。
2.Python Web 框架
1.Flask - 輕量級
2.Webpy - 輕量級
3.Tornado - 異步框架
4.Django - 重量級框架
3.框架模式
1.MTV
M :Models,模型層,主要負責數據庫建模、
T :Templates,模板層,用於處理用戶的顯示內容,如 html
V :Views,視圖,處理與用戶打交道的內容(請求和響應)
2.MVC
M :Models,模型層,主要負責數據庫建模
V :Views,視圖,處理用戶的顯示內容
C :Controller,控制器,用於與用戶交互的部份內容(請求和響應)html
M --- M T --- V V --- C
4.Flask框架
1.什麼是Flask框架
Flask是一個基於Python而且依賴於Jinja2模板引擎和Werkzeug WSGI服務的一個微型框架
WSGI :Web Server Gateway Interface(WEB服務網關接口)java
Flask是採用 MTV 的框架模式 2.安裝 Flask 1.查看已安裝的Flask版本 在 python 的交互模式中 : 1. import flask 沒報錯:已經安裝了Flask,能夠繼續查看版本 報錯:沒安裝Flask 2. flask.__version__ 已安裝Flask的狀況下,能夠查看安裝的版本 2.安裝Flask sudo pip3 install flask pip3 download flask 3.Flask 初始化 見代碼 ... ... 練習: 訪問路徑:http://localhost:5000/login : 在網頁中顯示 :歡迎訪問登陸頁面 訪問路徑:http://localhsot:5000/register 在網頁中顯示 :歡迎訪問註冊頁面
5.Flask - 路由(route)
1.什麼是路由
客戶端發送請求給web服務器,web服務器再將請求發送給Flask程序實例
程序實例須要知道每一個url請求所對應的運行代碼是誰。因此程序中必需要建立一個 url 請求地址 到 python運行函數的一個映射。處理url和函數之間的關係的程序就是"路由"
2.路由的體現
在 Flask 中,路由是經過 @app.route 裝飾器來表示的
1.路由的基本表示
# http://localhost:5000
@app.route('/')
def index():
return "xxx"python
# http://localhost:5000/admin/login @app.route('/admin/login') def admin_login(): return 'xxx' 2.帶參數的路由 路由中能夠攜帶參數表示不一樣的數據 http://localhost:5000/show/laowang http://localhost:5000/show/wangwc http://localhost:5000/show/laowang.gebi 1.基本帶參路由 @app.route('/show/<name>') def show(name): name : 表示的就是從地址欄上傳遞過來的數據 return 'xxx' 2.帶多個參數的路由 http://localhost:5000/show/laowang/36 @app.route('/show/<name>/<age>') def show(name,age): return 'xxx' 3.指定參數類型的路由 @app.route('/show/<name>/<int:age>') def show(name,age): name : 字符串 age : 整數 int: 類型轉換器 Flask 中所支持的類型轉換器: 類型轉換器 做用 缺省 字符串,不能有斜槓('/') int: 整型 float: 浮點型 path: 字符串,能夠有斜槓('/') 3.多 URL 的路由匹配 爲多個訪問地址匹配同一個視圖處理函數 @app.route('/地址1') @app.route('/地址2') ... ... def index(): return "" 練習: 當訪問路徑是如下任何一個的時候: http://localhost:5000 http://localhost:5000/index http://localhost:5000/數字 http://localhost:5000/index/數字 將程序交給 index() 視圖處理函數 判斷路由中到底有沒有數字傳遞進來, 若是有 響應 :您當前看的頁數爲 :xxx 若是沒有: 響應 :您當前看的頁數爲 :1 4.路由中設置 HTTP 請求方法 Flask路由也容許設置對應的請求方法(post/get),只有將匹配上請求方法的路徑才能交給對應的視圖處理函數取處理。全部的路由,默認只接受 get 請求 @app.route('/xxx/xxx',methods=['POST']) def xxx: # 該函數只能接受post請求 pass @app.route('/xxx/xxx',methods=['GET','POST']) def xxx: # 該函數既能接受get請求也能接受post請求 pass 5.URL的反向解析 正向解析:程序自動解析,根據@app.route()中的訪問路徑,來匹配處理函數 反向解析:經過視圖處理函數的名稱自動生成對應的訪問路徑 在Flask中要實現反向解析的話須要使用 : url_for(funName,args) funName:要生成地址的函數名 args:該地址中須要的參數
6.模板 - Templatesmysql
1.搭建結構
from flask import Flask
app = Flask(name)web
@app.route('/') def fun(): return "" if __name__ == "__main__": app.run(debug=True,port=6000)
2.路由
@app.route() 表示路由sql
@app.route('/') : 表示根路徑 / 首頁 @app.route('/index') : 表示 http://localhost:5000/index 1.帶參數路由 @app.route('/index/<name>') def index(name): return "" @app.route('/index/<name>/<gender>') def index(name,gender): return "" @app.route('/index/<int:age>') def index(age): return "" 類型轉換器: 默認 :字符串,不能包含 / int: :整型 float: :浮點型 path: :字符串,容許包含 / 2.多個訪問路徑交給同一視圖處理函數 http://localhost:5000/index http://localhost:5000/index/wangwc @app.route('/index') @app.route('/index/<name>') def index(name=None): if name is None : xxxx xxxx return ""
3.路由的反向解析
函數 :
s = url_for(funName,arg1=value1,arg2=value2)數據庫
M : Models 模型層
T : Templates 模板層
V : Views 視圖層
============================================
1.模板 - Templates
1.什麼是模板
模板 , 在Flask 中就是容許響應給用戶看的網頁
在模板中,容許包含"佔位變量"來表示動態的內容
模板最終也會被解析成字符串再響應給客戶端,這一過程一般稱爲"渲染"編程
Flask中的模板是依賴於 Jinja2 的模板系統 2.模板的設置 默認狀況下,Flask會在程序文件夾中的 templates 的子文件夾中搜索模板 默認狀況下,須要手動建立 templates 文件夾 3.模板的渲染 做用:在視圖中,將模板文件(xx.html)渲染成字符串以後,再響應給客戶端瀏覽器 函數:render_template('xxx.html') return render_template('xxx.html') 4.模板中的語法(重難點) 1.變量 變量是一種特殊的佔位符,告訴模板引擎該位置的值是從渲染模板時的數據中獲取出來的。 在視圖中 : @app.route('/') def index(): return render_template('xxx.html',變量1=值1,變量2=值2,..) return render_template('xxx.html',name='laowang',age=35) 在模板中 : {{變量名}} <h1>{{name}}</h1> 練習: 在 01-template.html基礎上,完成下列效果顯示: 歌名 :《綠光》 做詞 : 寶強 做曲 : 乃亮 演唱 : 羽凡 2.過濾器 1.什麼是過濾器 過濾器是容許在變量輸出前改變變量的值 2.語法 {{變量|過濾器}} Jinja2 模板中常見過濾器: 過濾器名 說明 capitalize 首字符變大寫,其餘變小寫 lower 將值轉換爲小寫 upper 將值轉換爲大寫 title 將值中的每一個單詞首字符變大寫 trim 去掉值兩邊的空格 3.標籤 1.什麼是標籤 每一個標籤標示的是不一樣的服務器端的功能 2.經常使用標籤 1. if 標籤 1.基本if結構 {% if 條件 %} {% endif %} 2.if ... else ... 結構 {% if 條件 %} 知足條件時要運行的代碼 {% else %} 不知足條件時要運行的代碼 {% endif %} 3.if ... elif ... elif ... else {% if 條件1 %} 知足條件1,要運行的代碼 {% elif 條件2 %} 知足條件2,要運行的代碼 {% elif 條件3 %} 知足條件3,要運行的代碼 {% else %} 以上條件都不知足的時候,要運行的代碼 {% endif %} 2. for 標籤 {% for 變量 in 元組|列表|字典 %} {% endfor %} 在 Jinja2 模板的循環中,支持內部變量 - loop loop做用:記載當前循環中的一些相關信息 loop 經常使用屬性: 1. index 用法:loop.index 做用:記錄當前循環的次數,從 1 開始記錄 2. index0 用法:loop.index0 做用:同上,從0開始記錄 3. first 用法:loop.first 做用:值爲True,則表示當前循環是第一次循環 4. last 用法:loop.last 做用:值爲True,則表示當前循環是最後一次循環 3. macro 標籤 (宏) 1.做用 至關因而在模板中聲明函數 2.語法 使用 {% macro %} 聲明宏 {% macro 名稱(參數列表) %} xxxx xxxx {% endmacro %} 3.在獨立的文件中聲明宏 1.建立 macro.html 模板文件 做用:定義項目中要用到的全部的宏 2.在使用的網頁中,導入 macro.html {% import 'macro.html' as macros %} 4. include 標籤 將其餘的模板文件包含到當前的模板文件中 語法:{% include 'xxx.html' %} 5.靜態文件處理 1.什麼是靜態文件 在Flask中不能與服務器動態交互的文件都是靜態文件 如:圖片,css文件,js文件,音視頻文件,... <img src="images/a.jpg"> <link rel="" href="css/a.css"> <script src="js/a.js"></script> <video src="mp4/a.mp4"></video> <audio src="music/a.mp3"></audio> 2.靜態文件的處理 1.全部的靜態文件必須放在名爲 static 的目錄中 static目錄要放在項目的根目錄處 FlaskDemo02 run01.py templates 01-xxx.html 02-xxx.html static images a.jpg b.jpg js body.js slider.js css 2.全部的靜態文件必須經過 /static/ 路徑訪問 /static/images/a.jpg /static 要到靜態資源目錄中繼續搜索
做業:
搭建 Blog 項目結構
1.建立項目 - Blog
2.將 全部的 html 文件 copy 到 templates 目錄中做爲模板
3.建立 static 目錄,將 js 目錄,css目錄,images目錄 copy到 static 中
4.建立 路由 /
訪問 根路徑時,顯示首頁模板(index.html)
要求:css,images,js 都能正常顯示
params = {
'author': '奧斯特羅夫斯基',
'dic': {'WWC': '隔壁老王', 'LZ': '呂澤', 'WMZ': '老魏', 'MM': '濛濛'},
'bookName': '鋼鐵是怎樣煉成的',
'tup': ('水滸傳', '三國演義', '紅樓夢', '西遊記'),
'price': 32.5,
'list': ['漩渦鳴人', '卡卡西', '自來也', '佐助'],
'person': <main.Person object at 0x7f157c2c9048>
}
params['author']
1.模板
1.模板設置
全部的模板默認要放在項目中的 templates 目錄中
2.渲染模板
html = render_template('xxx.html',args)
3.模板中的語法
1.變量
由後端的視圖傳遞給模板中的一些動態數據
模板:{{變量}}
2.過濾器
在變量輸出以前對變量進行一個修改
語法:{{變量|過濾器}}
ex:
{{var|upper}}
{{var|title}}
{{var|capitalize}}
... ...
3.標籤
1. if 結構
1. {% if 條件 %} ... {% endif %}
2.
{% if 條件 %}
...
{% else %}
...
{% endif %}
3.
{% if 條件1 %}
...
{% elif 條件2 %}
...
{% else %}
...
{% endif %}
2. for 結構
{% for 變量 in 列表|字典|元組 %}
{% endfor %}
內置變量 :loop loop.index : 當前循環遍歷的次數,以 1 做爲起始值 loop.index0: 同上,以 0 做爲起始值 loop.first : True的話則表示是第一次循環 loop.last : True的話則表示是最後一次循環 4.宏 {% macro 名稱(參數) %} ... {% endmacro %} {{名稱(參數)}} 在 macro.html 中聲明全部的宏 macro.html {% macro 名稱1(參數) %} ... {% endmacro %} {% macro 名稱1(參數) %} ... {% endmacro %} 在使用的網頁中,引入 macro.html {% import 'macro.html' as macros %} {{macros.名稱(參數)}} 5包含 {% include 'xxx.html' %}
2.靜態文件
1.全部的靜態文件必須保存在 static 目錄中
static 目錄 存放在 項目根目錄下的
2.全部的靜態文件的訪問必須經過 /static
/static 告訴服務器取 static 目錄中繼續搜索剩餘內容
=========================================================
1.模板
1.靜態文件地址的反向解析
url_for('static',filename='
ex:
url_for('static',filename='images/b041.jpg')
結果: /static/images/b041.jpg
2.模板的繼承
1·什麼是模板的繼承
模板的繼承相似於類的繼承,若是一個模板中出現的內容來自於另外一個模板的話,那麼就可使用繼承的方式來簡化開發
2.語法
1.父模板
須要定義出哪些東西在子模板中是能夠被重寫的
{% block 塊名 %}
父模板中正常顯示的內容
{% endblock %}
block:
1.在父模板中是能夠正常顯示的,沒有任何影響
2.在字模板中是能夠被重寫的
2.子模板
1.須要指定繼承自哪一個父模板
{% extends '父模板名稱' %}
2.重寫父模板中對應的內容
{% block 塊名 %}
此處編寫的內容會覆蓋掉父模板中同名block的內容
容許經過 {{super()}} 來調用父模板中的內容 {% endblock %}
2.修改配置
1.構建Flask 應用時容許指定的配置信息
app=Flask(
name,
template_folder='muban',
static_url_path='/s',
static_folder='/sta')
template_folder : 指定存放模板的文件夾名稱 static_url_path : 訪問靜態資源的路徑 http://localhost:5000/s/xxx 查找靜態資源文件 static_folder : 指定存放靜態文件的目錄名稱 在項目的根目錄中 ,有一個名爲 sta 的目錄用於存放靜態文件 2.啓動程序的運行配置 app.run( debug = True, port = 5555, host = '0.0.0.0' ) host : 指定訪問地址,0.0.0.0 表示局域網內的任何機器均可以訪問網站
3.請求(request) 和 響應(response)
1.HTTP協議
Request Headers - 請求消息頭
Response Headers - 響應消息頭
2.請求對象 - request
request - 請求對象,封裝了全部與請求相關的信息。如:請求數據,請求消息頭,請求路徑,... ...
在Flask中,要使用 request 的話,必須先導入
from flask import request
1.request的經常使用成員 1.scheme : 獲取請求方案(協議) 2.method : 獲取本期請求的請求方式(重點) 3.args : 獲取使用get請求方式提交的數據 4.form : 獲取使用post請求方式提交的數據 5.cookies : 獲取 cookies 的相關信息 6.headers : 獲取 請求消息頭 的相關信息 7.files : 獲取上傳的文件 8.path : 獲取請求的url地址(進入到主機後的請求資源地址,不包含請求參數) 9.full_path : 獲取請求的url地址(進入到主機後的請求資源地址,包含請求參數) 10.url : 獲取完整的請求地址,從協議開始的地址 2.獲取請求提交的數據 1.get 請求方式 1.表單容許實現get請求 <form action="" method="get"> 姓名:<input name="uname"> </form> 2.在請求地址後拼請求提交的參數 http://localhost:5000/06-get?uname=xxx&upwd=xxx 獲取 get 請求方式提交的數據 : request.args 封裝的是get請求的數據 2.post 請求方式 post請求只有在表單中才可以被觸發 <form method="post"> 獲取 post 請求提交的數據 : request.form 封裝的就是 post 請求的數據,類型爲字典 request.form['name'] : 獲取 name 對應的值 request.form.get('name') : 獲取 name 對應的值 request.form.getlist('name') : 獲取 name 列表數據(如複選框,下拉列表) 練習: 1.訪問地址爲 http://localhost:5000/07-form-post 可以去往07-form.html模板 2.在 07-form.html 中 包含一個表單,post 提交方式,提交地址爲 /07-post,控件以下 1.文本框 - 用戶名 2.密碼框 - 用戶密碼 3.文本框 - 用戶郵箱 4.文本框 - 真實姓名 5.提交按鈕 3.在 07-post 中 獲取全部請求提價的數據並打印在終端中
['class', 'delattr', 'dict', 'dir', 'doc', 'enter', 'eq', 'exit', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', 'le', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', '_cached_json', '_get_data_for_json', '_get_file_stream', '_get_stream_for_parsing', '_load_form_data', '_parse_content_type', 'accept_charsets', 'accept_encodings', 'accept_languages', 'accept_mimetypes', 'access_route', 'application', 'args', 'authorization', 'base_url', 'blueprint', 'cache_control', 'charset', 'close', 'content_encoding', 'content_length', 'content_md5', 'content_type', 'cookies', 'data', 'date', 'dict_storage_class', 'disable_data_descriptor', 'encoding_errors', 'endpoint', 'environ', 'files', 'form', 'form_data_parser_class', 'from_values', 'full_path', 'get_data', 'get_json', 'headers', 'host', 'host_url', 'if_match', 'if_modified_since', 'if_none_match', 'if_range', 'if_unmodified_since', 'input_stream', 'is_json', 'is_multiprocess', 'is_multithread', 'is_run_once', 'is_secure', 'is_xhr', 'json', 'list_storage_class', 'make_form_data_parser', 'max_content_length', 'max_form_memory_size', 'max_forwards', 'method', 'mimetype', 'mimetype_params', 'on_json_loading_failed', 'parameter_storage_class', 'path', 'pragma', 'query_string', 'range', 'referrer', 'remote_addr', 'remote_user', 'routing_exception', 'scheme', 'script_root', 'shallow', 'stream', 'trusted_hosts', 'url', 'url_charset', 'url_root', 'url_rule', 'user_agent', 'values', 'view_args', 'want_form_data_parsed']
Accept-Encoding: gzip, deflate
Cookie: csrftoken=n5KInc6ybogDshzgCIGsNgKuPLCIWv1Aus1twEtssK1TkZglnD51NlBa4axghzg1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0
Host: localhost:5000
Connection: keep-alive
Cookie: csrftoken=n5KInc6ybogDshzgCIGsNgKuPLCIWv1Aus1twEtssK1TkZglnD51NlBa4axghzg1
Host: localhost:5000
Upgrade-Insecure-Requests: 1
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Referer: http://localhost:5000/02-parent
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
http://localhost:5000/06-get?uname=wangwc&upwd=lvze
http://localhost:5000/06-get?uname=laowei&upwd=wangwc
1.模板繼承
1.父模板
{% block 塊名 %}
{% endblock %}
2.子模板
1.{% extends '父模板名稱' %}
2.{% block 塊名 %} ... {% endblock %}
2.修改配置
1.建立應用的配置
app=Flask(
name,
template_folder="xxx",
static_url_path="/s",
static_folder="xxx")
2.啓動應用時的配置
app.run(
debug=True,
port="5678",
host="0.0.0.0"
)
3.請求
1.請求對象 - request
1.request
from flask import request
@app.route('/xxx') def xxx(): request : 能夠表示請求的相關信息 2.request的經常使用成員 1.request.scheme 2.request.method 3.request.args 4.request.form 5.request.cookies 6.request.url(完整路徑) 7.request.path(不帶參數) 8.request.full_path(帶參數) 9.request.headers request.headers.get('Referer','') request.headers.get('消息頭','') 3.獲取請求提交的數據 1.GET 請求 1.表單 method=get 2.全部地址欄的請求都是get 特色:http://localhost:5000/login?uname=xx&uage=5 取值: request.args['uname'] request.args.get('uage') 2.POST 請求 1. 表單 method='post' 取值: request.form[''] request.form.get('') 想看登陸頁面: /login 在/login中,想提交數據給服務器:/login 在 /login 中,要判斷用戶的請求方法 若是是 get 的話,則去往 登陸頁面 若是是 post的話,則處理用戶提交的數據
======================================================
1.響應(response)
1.什麼是響應
響應就是由服務器端帶給客戶端的內容,對應着請求。
響應能夠是普通的字符串,模板 或 重定向
return "普通字符串"
return render_template('xxx.html')
2.響應對象
響應對象:將響應的內容封裝到一個對象中,能夠完成更多的響應的行爲(如:增長cookies,...)
在Flask中,使用 make_response() 構建響應對象 from flask import make_response @app.route('/xxx') def xxx(): resp = make_response('響應內容') # 容許實現其餘的響應行爲 return resp 3.重定向 1.什麼是重定向 由服務器端通知客戶端從新向一個新的地址發送請求 2.語法 from flask import redirect return redirect('重定向地址') =============================== resp = redirect('重定向地址') #藉助resp實現其餘的響應行爲 return resp
2.文件上傳
1.注意問題
表單中若是有文件上傳的話,必須遵循如下兩個要求
1.提交方式 method 必須爲 post
2.表單的 enctype 屬性的值 必須爲 multipart/form-data
2.服務器端
1.經過 request.files 獲取上傳文件
f = request.files['文件框的name值']
2.經過 f.save(保存路徑) 將文件保存至指定目錄處
經過 f.filename 獲取文件的名稱
f.save('static/'+f.filename)
3.模型 - Models
1.什麼是模型
模型,是根據數據庫中表的結構而建立出來的class。
每一張表對應到編程語言中,就是一個class
表中的每個列對應到編程語言中就class中的一個屬性
2.模型的框架 - ORM
1.什麼是ORM
ORM :Object Relational Mapping
簡稱: ORM,O/RM ,O/R Mapping
中文名:對象關係映射
2.ORM的三大特徵
1.數據表(table)到編程類(class)的映射
數據庫中的每一張表 對應到 編程語言中 都有一個類
在ORM中:
容許將數據表 自動 生成一個類
容許將類 自動 生成一張數據表
2.數據類型的映射
將數據庫表中的字段以及數據類型 對應到 編程語言中類的屬性
在ORM中
容許將表中的字段和數據類型自動映射到編程語言中
也容許將類中的屬性和數據類型也自動映射到表中
3.關係映射
將數據庫中表與表之間的關係 對應 到編程語言中類與類之間的關係
數據庫中表與表之間的關係:
1.一對一
外鍵,主鍵,惟一約束
A表中的一條數據只能與B表中的一條數據相關聯
2.一對多
外鍵,主鍵
A表中的一條數據能夠與B表中的任意多條數據相關聯,反之,B表中的一條數據只能與A表中一條數據相關聯
ex:老師(Teacher)與課程(Course)
一門課程能夠被多個老師所教授
一個老師最多隻能教一門課程
3.多對多
經過第三張關聯表去關聯兩張表
A表中的一條數據能夠與B表中的任意多條數據相關聯,B表中的一條數據也能夠與A表中的任意多條數據相關聯
3.ORM優勢
1.封裝了數據庫中全部的操做,大大提升了開發效率
2.能夠省略龐大的數據訪問層,即使不用SQL編碼也能完成對數據的CRUD的操做
3.Flask 中的 ORM框架
1.數據庫 和 框架配置
在Python 和 Flask 中,使用的ORM框架是 - SQLAlchemy
在Flask 中想使用 SQLAlchemy的話,須要進行安裝:
pip3 install sqlalchemy
pip3 install flask-sqlalchemy
2.建立數據庫
Student (id,stu_name)
Course (id,course_name)
Student_Course (id,student_id,course_id)
select s.stu_name,c.course_name from Student as s
inner join Student_Course as sc
on s.id = sc.student_id
inner join Course as c
on sc.course_id = c.id
where s.stu_name='馬暈'
消息頭:
Content-Type
Referer
@app.route('/show/
def show(name):
name : 參數
http://localhost:5000/show/wangwc
1.響應對象
1.響應對象
resp = make_response("")
return resp
2.重定向
由服務器通知瀏覽器向新的地址發送一個請求
resp = redirect('/xxx')
return resp
2.文件上傳
1.注意問題
表單的method必須爲 post
表單的enctype必須爲 multipart/form-data
2.服務器端
1.request.files 獲取上傳的文件
f = request.files['xx']
2.將文件保存至服務器的指定目錄處
f.save('保存路徑')
1.獲取項目的絕對路徑 basedir = os.path.dirname(__file__) 2.經過時間字符串代替文件名稱 1.獲取當前的時間字符串 ftime = datetime.datetime.now().strftime("%Y%m%d%H%M%S%f") 2.獲取文件擴展名 ext = f.filename.split('.')[1] 3.拼完整的上傳路徑 upload_path=os.path.join(basedir,'static/upload',ftime+'.'+ext)
3.ORM
1.ORM
1· 中文名:對象關係映射
2. ORM三大特徵
1.數據表 到 編程類的映射
2.數據類型的映射
3.關係映射
2.Python 和 Flask 中 使用 ORM
Python 和 Flask :SQLAlchemy
Flask :必需要有 Flask-SQLAlchemy 的支持
3.Flask中配置數據庫
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI']="mysql://root:123456@localhost:3306/flask" db = SQLAlchmey(app) ===============================================
1.模型 - Models
1.定義模型
模型:數據庫中的表在編程語言中的體現,其本質就是一個python類(模型類 或 實體類)
語法: class MODELNAME(db.Model): __tablename__="TABLENAME" COLUMN_NAME=db.Column(db.TYPE,OPTIONS) 1.MODELNAME : 定義模型類的名稱,根據表名設定 2.TABLENAME : 映射到數據庫中表的名稱 3.COLUMN_NAME : 屬性名,映射到數據表就是列名 4.TYPE : 映射到列的數據類型 5.OPTIONS : 列選項 db.TYPE 列類型以下: 類型名 python類型 說明 Integer int 普通整數,32位 SmallInteger int 小範圍整數,一般16位 BigInteger int或long 不限精度整數 Float float 浮點數 Numeric decimal.Decimal 定點數 String str 變長字符串 Text str 變長字符串,優化 Unicode unicode 變長Unicode字符串 UnicodeText unicode 優化後的變長Unicode串 Boolean bool 布爾值 Date datetime.date 日期 Time datetime.time 時間 DateTime datetime.datetime日期和時間 OPTIONS 列選項: 選項名 說明 primary_key 若是設置爲True表示該列爲主鍵 unique 若是設置爲True表示該列值惟一 index 若是設置爲True表示該列要建立索引 nullable 若是設置爲True表示該列容許爲空 default 表示該列的默認值 練習: 1.建立 Student 模型類 表名:student 字段: 1.id ,主鍵,自增 2.sname , 姓名,長度爲30而且不容許爲空的字符串 3.sage,年齡,整數 2.建立 Teacher 模型類 表名:teacher 字段: 1.id , 主鍵,自增 2.tname ,姓名,長度爲30而且不容許爲空的字符串 3.tage,年齡,整數 3.建立Course 模型類 表名:course 字段: 1·id,主鍵,自增 2·cname ,課程名稱長度爲30而且不容許爲空的字符串 2.數據庫操做 - 插入 1.建立實體對象 2.完成插入 db.session.add(實體對象) db.session.commit() 3.數據庫操做 - 查詢 1.基於 db.session 進行查詢 1.db.session.query() 該函數會返回一個Query對象,類型爲BaseQuery 該對象中包含了實體類對應的表中的全部的數據 該函數能夠接收一個或多個參數,參數們表示的是要查詢的實體對象是誰 2.查詢執行函數 目的:在query()的基礎上獲得最終想要的結果 語法:db.session.query(...).查詢執行函數() 函數 說明 all() 以列表的方式返回query()中全部查詢函結果 first() 返回查詢結果中的第一個結果,若是沒有結果,則返回None first_or_404() 返回查詢結果中的第一個結果,若是沒有結果的話,則終止並返回404 count() 返回查詢結果的數量 3.查詢過濾器函數 做用:在查詢的基礎上,篩選部分行數據 語法:db.session.query(...).過濾器函數().查詢執行函數() 過濾器函數 說明 filter() 按指定條件進行過濾(多表,單表,定值,不定值) filter_by() 按等值條件過濾時使用 limit() 按限制行數獲取 order_by() 根據指定條件進行排序 group_by() 根據指定條件進行分組 過濾器函數詳解: 1.filter() 注意:條件必須由 模型類.屬性 構成 1.查詢年齡大於30的Users的信息 db.session.query(Users).filter(Users.age>30).all() 2.查詢年齡大於30而且id大於1的Users的信息 db.session.query(Users).filter(Users.age>30,Users.id>1).all() 3.查詢年齡大於30或者id大於1的Users的信息 注意:查詢 或 的操做,要藉助於 or_() db.session.query(Users).filter(or_(Users.age>30,Users.id>1)).all() 4.查詢id爲2的Users的信息 注意:等值判斷必須用 == db.session.query(Users).filter(Users.id==2).all() 5.查詢 email 中包含 'w' 的Users的信息 - 模糊查詢 注意:模糊查詢like須要使用實體類中屬性提供的like() db.session.query(Users).filter(Users.email.like('%w%')).all() 6.查詢 id 在 [2,3] 之間的 Users 的信息 注意:模糊查詢in須要使用實體類中屬性提供的in_([]) 2.聚合函數 db.session.query(func.聚合函數(列名).label('別名')).all() 3.filter_by() 查詢 id=5的Users的信息 db.session.query(Users).filter_by(id=5).all() 4.limit() result = db.session.query(Users).limit(2).all() result = db.session.query(Users).limit(2).offset(1).all() 5.order_by() # 按照id列的值降序排序 db.session.query(Users).order_by("id desc") # 按照age列的值降序排序,二級排序按照id升序排序 db.session.query(Users).order_by("age desc,id asc").all() 6.group_by() db.session.query(Users).group_by('age').all() 2.基於 Models 類進行查詢
數據庫中的一行:實體
實體完整性:表中的實體不能徹底重複 - 主鍵
SELECT users.id AS users_id, users.username AS users_username, users.age AS users_age, users.email AS users_email
FROM users
SELECT users.id AS users_id, users.username AS users_username, users.age AS users_age, users.email AS users_email, course.id AS course_id, course.cname AS course_cname
FROM users, course
查詢Users中全部人的年齡的總和
select sum(age) as 'sum_age' from users
select id,sum(age) as 'sum_age' from users
db.session.query(Users.id,func.sum('age'))
select * from users limit 1,2
1.建立模型
class MODLENAME(db.Model):
tablename=TABLENAME
COLUMN_NAME=db.Column(db.TYPE,OPTIONS)
MODELNAME : 模型名稱 TABLENAME : 對應的表名 COLUMN_NAME : 對應的列名 TYPE : 列類型 OPTIONS : 列選項 TYPE: Integer,SmallInteger,BigInteger,Boolean Float,Numeric String,Text,Unicode,UnicodeText Date,Time,DateTime OPTIONS: primary_key : True or False unique : True or False index : True or False nullable : True or False 默認是容許爲空(True) default : 定義默認值
2.數據庫操做
1.插入
db.session.add(Models對象)
db.session.commit()
自動提交: app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN']=True 2.查詢 1.基於 db.session 查詢 1.db.session.query() 查詢基礎,返回查詢對象 2.查詢執行函數 目的:用於獲得最終的結果 all() , first() , first_or_404() , count() 3.查詢過濾器函數 目的:在基礎查詢後增長篩選條件 1.filter() 注意:必須使用 實體類.屬性 作篩選 1.db.session.query(Models).filter(Models.column > num).all() 2.db.session.query(Models).filter(Models.col1>num1,Models.col2>num2) 3.db.session.query(Models).filter(or_(條件1,條件2)).all() 4.db.session.query(Models).filter(Models.column.like('%w%')).all() 5.db.session.query(Models).filter(Models.column.in_(['','',''])).all() 6.聚合 db.session.query(func.聚合函數(Models.Column).label('別名')) 聚合函數: sum() : 求和 count() : 求數量 max() min() avg() 2.filter_by() 3.limit() 4.order_by() 5.group_by() 2.基於 Models
=================================================
1.數據庫的操做
1.增長(略)
2.查詢
1.基於db.session(略)
2.基於Models進行查詢
Models.query.查詢過濾器函數(條件參數).查詢執行函數()
3.刪除
1.查詢出要刪除的實體對象
u=db.session.query(Models).filter_by(xxx).first()
2.根據提供的 刪除方法進行刪除
db.session.delete(u)
注意:
真正的刪除並非經過刪除操做完成,而是經過修改完成的
4.修改
1.查
將 要修改的信息查詢出來
2.改
實體對象.屬性 = 值
3.保存
db.session.add(實體對象)
2.關係映射
1.一對多
語法:
1.在 "多" 的實體中
增長一個列,引用自"一"表的主鍵列
外鍵列名 = db.Column(db.Integer,db.ForeignKey('主表.主鍵'))
2.在 "一" 的實體中
增長關聯屬性以及反向引用關係
ex: 關聯屬性: 在 course 對象中,經過一個屬性可以獲得對應的全部的teacher們 關聯屬性,是應該加在 Course 的實體類中 反向引用: 在 teacher 對象中,經過一個屬性可以獲得對應的course 反向引用關係屬性,是應該加在 Teacher 的實體類中 增長關聯屬性和反向引用關係: 屬性名=db.relationship('多表實體類名',關係選項) 關係選項: 選項名 說明 backref 在關係的另外一個模型中添加的反向引用屬性名 (準備在"多"的實體中增長對"一"的實體引用的屬性名) lazy 指定如何加載當前的相關記錄 select:首次訪問時加載記錄 immediate:源對象加載後立刻加載相關記錄 subquery:效果同上,利用子查詢方式加載記錄 noload:永不加載記錄 dynamic:默認不加載記錄,但會提供加載記錄的查詢 uselist 若是設置爲False,表示不使用列表表示關聯數據,而使用標量 secondary 指定多對多關係映射中的關聯表的名字 2.一對一 1.什麼是一對一 A表中的一條記錄只能與B表中的一條記錄相關聯 B表中的一條記錄只能與A表中的一條記錄相關聯 2.在SQLAlchemy中的體現 1.在任意一個類中增長 外鍵列名 = db.Column(db.Integer,db.ForeignKey('主鍵表.主鍵列')) 2.在另一個類中增長 關聯屬性 和 反向引用關係屬性 屬性=db.relationship('關聯的實體類',backref='反向引用屬性名',uselist=False) <a href="javascript:xxxx()">xxx</a>
1.數據庫的操做
1.查詢 - 基於 Models 查詢
Models.query.查詢過濾器().查詢執行函數()
2.修改
1.查
獲得數據
2.改
經過實體對象修改數據
3.保存
db.session.add(實體)
3.刪除
db.session.delete(實體)
2.關係映射
1.一對多
1.在 "多" 實體中
外鍵列名=db.Column(db.Integer,db.ForeignKey('主表.主鍵'))
2.在 "一" 實體中
屬性名=db.relationiship("多的實體類名",backref="屬性名",lazy="dynamic")
lazy:指定如何加在相關記錄 1.select 首次訪問時加載 2.immediate 源對象加載後立馬加載相關數據 3.subquery 效果同上,使用的是子查詢 4.noload 永不加載 5.dynamic 不加載記錄,但提供加載記錄的查詢 uselist: 若是設置爲False,表示不使用列表而使用的是標量 secondary: 指定多對多關係中關聯表的名字 2.一對一 1.在 "多" 實體類中體現 外鍵列名=db.Column(db.Integer,db.ForeignKey('主表.主鍵')) 2.在 "一" 實體類中體現 屬性名 = db.relationship("關聯的實體類",backref="",uselist=False)
=========================================================
1.關係映射
1.多對多
1.什麼是多對多
A表中的一條數據能夠與B表中任意多條數據相關聯
B表中的一條數據能夠與A表中任意多條數據相關聯
2.實現
在數據庫中使用第三張表(關聯表)
在編程語言中,能夠不編寫對應的實體類
1.建立第三張表
student_course = db.Table(
'student_course',#在數據庫中表名
db.Column('id',db.Integer,primary_key=True),
db.Column(
'student_id',
db.Integer,
db.ForeignKey('student.id')),
db.Column(
'course_id',
db.Integer,
db.ForeignKey('course.id'))
)
2.cookies / cookie
1.什麼是cookies
cookie 是一種數據存儲手段
將一段文本保存在客戶端(瀏覽器)的一種手段,並能夠長時間保存
2.cookies的使用場合
1.記住密碼
2.記住搜索關鍵詞
3.Flask 中使用 cookies
1.使用響應對象,將數據保存進cookies(客戶端)
1.resp = make_response("字符串"|render_template())
2.resp = redirect('地址')
cookies 的語法 響應對象.set_cookie(key,value,max_age) key:保存的cookie的名稱 value:保存的cookie的值 max_age:保存的時間,取值爲數字,默認以 s 爲單位 60 :一分鐘 60 * 60 :一小時 60 * 60 * 24 :一天 60 * 60 *24 * 365 :一年 2.獲取 cookie 的值 每次向服務器發送請求時,都會把cookie中的數據封裝到request中並帶到服務器上 在flask中經過 request.cookies 獲取全部的cookies值 3.刪除cookie的值 響應對象.delete_cookie('key') { 'uname': 'jack', 'csrftoken': 'n5KInc6ybogDshzgCIGsNgKuPLCIWv1Aus1twEtssK1TkZglnD51NlBa4axghzg1' }
3.session - 會話
1.什麼是session
session是保存在服務器上,爲每一個瀏覽器所開闢的一段空間
2.session 在 Flask 中的實現
1.配置 SECRET_KEY
app.config['SECRET_KEY']="xiangxieshaxiesha"
2.使用session
from flask import session
1.向session中保存數據 session['key']=value 2.從session中取值 value = session['key'] value = session.get('key','') 3.從session中刪除數據 del session['key']