flask做web基礎
阿新 • • 發佈:2020-09-17
flask是python的一個web微框架 做演示demo/或者簡單網頁工具十分方便
安裝flask:pip install flask
用來做一個正式網站還是需要配置良好的目錄結構
flask-demo/
├ run.py # 應用啟動程式
├ config.py # 環境配置
├ requirements.txt # 列出應用程式依賴的所有Python包
├ tests/ # 測試程式碼包
│ ├ __init__.py
│ └ test_*.py # 測試用例
└ myapp/
├ admin/ # 藍圖目錄
├ static/
│ ├ css/ # css檔案目錄
│ ├ img/ # 圖片檔案目錄
│ └ js/ # js檔案目錄
├ templates/ # 模板檔案目錄
├ __init__.py
├ forms.py # 存放所有表單,如果多,將其變為一個包
├ models.py # 存放所有資料模型,如果多,將其變為一個包
└ views.py # 存放所有檢視函式,如果多,將其變為一個包
最簡單測試:test.py
python test.py 後,瀏覽器輸入localhost:5000就能看到網頁顯示Hello world。 或者輸入:127.0.0.1:5000
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World'
if __name__ == '__main__':
app.debug = True # 設定除錯模式,生產模式的時候要關掉debug
app.run()
Jinja2是一個廣泛應用的模板引擎,可以很方便的把資料嵌入到網頁問價中
from flask import Flask
from flask import render_template
app = Flask(__name__)
@app.route('/hello')
@app.route('/hello/<name>')
def hello(name=None):
#渲染hello.html模板,把name資料傳入進去
return render_template('hello.html', name=name)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
#模版檔案:hello.html ”http://localhost:5000/hello/world”
<!doctype html>
<title>Hello Sample</title>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello World!</h1>
{% endif %}
#模板繼承 #father.html
<!doctype html>
<title>Hello Sample</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
<div class="page">
{% block body %}
{% endblock %}
</div>
#繼承上面模板
{% extends "father.html" %}
{% block body %}
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello World!</h1>
{% endif %}
{% endblock %}
會話session 記錄已登入資訊,避免重複進入登入頁面
from flask import Flask,url_for,request,render_template,redirect,session
@app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
if request.form['user'] == 'admin':
session['user'] = request.form['user']
return 'Admin login successfully!'
else:
return 'No such user!'
if 'user' in session:
return 'Hello %s!' % session['user']
else:
title = request.args.get('title', 'Default')
return render_template('login.html', title=title)
@app.route('/logout')
def logout():
session.pop('user', None)
return redirect(url_for('login'))
app.secret_key = '123456'
if __name__ == "__main__":
app.run(debug=True)
使用Cookie
from flask import Flask,url_for,request,render_template,redirect,session,make_response
import time
@app.route('/login', methods=['POST', 'GET'])
def login():
response = None
if request.method == 'POST':
if request.form['user'] == 'admin':
session['user'] = request.form['user']
response = make_response('Admin login successfully!')
#設定Cookie,儲存在瀏覽器中,第三個引數max_age設定有效期(秒),不設定則瀏覽器關閉後失效
response.set_cookie('login_time', time.strftime('%Y-%m-%d %H:%M:%S'))
...
else:
if 'user' in session:
#”request.cookies”物件就是一個儲存了瀏覽器Cookie的字典,使用其”get()”函式就可以獲取相應的鍵值。
login_time = request.cookies.get('login_time')
response = make_response('Hello %s, you logged in on %s' % (session['user'], login_time))
...
return response
app.secret_key = '123456' #設定祕鑰,最好使用隨機
if __name__ == "__main__":
app.run(debug=True)
錯誤處理
from flask import Flask,abort
app = Flask(__name__)
@app.route('/error')
def error():
abort(404) #直接退出
@app.errorhandler(404)
def page_not_found(error):
return render_template('404.html'), 404 #返回重寫的錯誤頁面
if __name__ == "__main__":
app.run(debug=True)
URL重定向:
#不帶/時,Flask會自動重定向到正確地址。
@app.route('/projects/')
def projects():
return 'The project page'
#末尾帶上/後Flask會直接報404 NOT FOUND錯誤
@app.route('/about')
def about():
return 'The about page'
---------------------------------------------
from flask import session, redirect
@app.route('/')
def index():
if 'user' in session:
return 'Hello %s!' % session['user']
else:
#redirect()”函式當客戶端瀏覽某個網址時,將其導向到另一個網址
#“redirect()”的第二個引數時HTTP狀態碼,可取的值有301, 302, 303, 305和307,預設即302
return redirect(url_for('login'), 302)
#上傳檔案 #werkzeug 判斷檔名是否安全 pip install werkzeug #服務端:
from flask import Flask, request
from werkzeug.utils import secure_filename
import os
app = Flask(__name__)
#配置資訊 上傳目錄
app.config['UPLOAD_FOLDER'] = 'static/uploads/'
#控制上傳檔案的大小
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 #16MB
#上傳檔案格式,字尾名
app.config['ALLOWED_EXTENSIONS'] = set(['png', 'jpg', 'jpeg', 'gif'])
# For a given file, return whether it's an allowed type or not
def allowed_file(filename):
return '.' in filename and
filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']
@app.route('/')
def hello_world():
return 'hello world'
@app.route('/upload', methods=['POST'])
def upload():
upload_file = request.files['image01']#圖片以"image01"標識
file_content = request.files['image01'].stream.read()#獲取上傳檔案的內容
if upload_file and allowed_file(upload_file.filename):
filename = secure_filename(upload_file.filename)
#路徑
upload_file.save(os.path.join(app.root_path, app.config['UPLOAD_FOLDER'], filename))
return 'hello, '+request.form.get('name', 'little apple')+'. success'
else:
return 'hello, '+request.form.get('name', 'little apple')+'. failed'
if __name__ == '__main__':
app.run(debug=True)
客戶端
import requests
#當前目錄下的 01.jpg上傳到伺服器
files = {'image01': open('01.jpg', 'rb')}
user_info = {'name': 'letian'}
r = requests.post("http://127.0.0.1:5000/upload", data=user_info, files=files)
#coding=utf-8
from flask import Flask
from flask import request
app = Flask(__name__)
#路由 是指url/register只接受POST方法。也可以根據需要修改methods引數
@app.route("/login", methods=["GET", "POST"])
def hello_str():
if request.method == "POST":
print(request.headers) #請求頭
#多種接收資料方法
username = request.form['username']
username = request.form.get("username",type = str,default="admin") #獲取表單資料
#對應請求requests.post(url, json.dumps(params)) as_text=True 變成Unicode 使用 json.loads()轉換字典
params = request.get_data(as_text=True)
params = request.get_json()
params = request.data
elif request.method == "GET":
username = request.args.get("username") #獲取get請求引數
username = request.values.get("username") #獲取所有有請求引數
return redirect(url_for('home',username=request.form['username']))
@app.route('/home')
def home():
return render_template('home.html', username=request.args.get('username'))
if __name__ == "__main__":
#要控制上產檔案的大小,可以設定請求實體的大小,檔案
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 #16MB
app.debug = True
app.run('0.0.0.0',80)
#post 請求
import requests, json user_info = {'name': 'letian'}
headers = {'content-type': 'application/json'}
r = requests.post("http://127.0.0.1:5000/json", data=json.dumps(user_info), headers=headers)
print r.headers
print r.json()
構建相應 自己設定相應引數返回
from flask import Flask,url_for,request,render_template,redirect,session,make_response
@app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
...
if 'user' in session:
...
else:
title = request.args.get('title', 'Default')
response = make_response(render_template('login.html', title=title), 200)
response.headers['key'] = 'value'
return response
if __name__ == "__main__":
app.run(debug=True)
request相關屬性
form 接收POST/PUT請求資料,MultiDict
arges MultiDict如searchword = request.args.get('key', '')
values 可以代替form和args
cookies 請求的cookies,型別是dict
headers 請求頭,型別是dict
data 包含請求的資料,轉為字串,處理不了mimetype
files MultiDict,帶有POST/PUT請求上傳的檔案
environ WSGI環境配置
method 請求方法,如GET,POST
path 獲取請求檔案路徑
base_url 獲取域名與請求檔案路徑
url 獲取全部url
url_root 獲取域名
blueprint 藍圖名字
endpoint endpoint匹配請求
json 如果mimetype是application/json,會解析json,不是則返回None,可替代get_json()
max_content_length 返回MAX_CONTENT_LENGTH的配置鍵
view_args = None 一個匹配請求的view引數的字典,當匹配的時候發生異常,會返回None。
get_json(force=False, silent=False, cache=True)
下面的應該用不到,搬運過來
on_json_loading_failed(e)
module 如果請求是傳送到一個實際的模組,則該引數返回當前模組的名稱。這是棄用的功能,使用blueprints替代。
routing_exception = None 如果匹配URL失敗,這個異常將會/已經丟擲作為請求處理的一部分。這通常用於NotFound異常或類似的情況。
url_rule = None 內部規則匹配請求的URL。這可用於在URL之前/之後檢查方法是否允許(request.url_rule.methods) 等等。
預設情況下,在處理請求函式中寫下print('request.url_rule.methods', request.url_rule.methods)
會列印:
request.url_rule.methods {‘GET’, ‘OPTIONS’, ‘HEAD’}