Flask从入门到放弃(介绍、模版语法案例、配置文件、路由本质、CBV整体流程)
文章目錄
- 一、Flask介紹
- 二、Flask快速使用
- 三、Flask展示用戶信息案例
- 四、Flask配置文件
- 五、路由系統
- 1)路由系統
- 2)路由本質
- 3)Add_url_rule的參數
- 六、Flask的CBV
- 1)CBV的寫法
- 2)CBV添加裝飾器
- 3)as_view的執行流程
- 4)Login.as_view(name='index') name到底有什么用?
- 5)CBV中得methods作用
- 七、模板語法
一、Flask介紹
Flask是一個使用 Python 編寫的輕量級 Web 應用框架,其 WSGI 工具箱采用 Werkzeug ,模板引擎則使用 Jinja2 。對于Werkzeug本質是Socket服務端,其用于接收http請求并對請求進行預處理,然后觸發Flask框架,開發人員基于Flask框架提供的功能對請求進行相應的處理,并返回給用戶,如果要返回給用戶復雜的內容時,需要借助Jinja2模板來實現對模板的處理,即:將模板和數據進行渲染,將渲染后的字符串返回給用戶瀏覽器。
“微”(micro) 并不表示你需要把整個 Web 應用塞進單個 Python 文件(雖然確實可以 ),也不意味著 Flask 在功能上有所欠缺。微框架中的“微”意味著 Flask 旨在保持核心簡單而易于擴展。Flask 不會替你做出太多決策——比如使用何種數據庫。而那些 Flask 所選擇的——比如使用何種模板引擎——則很容易替換。除此之外的一切都由可由你掌握。如此,Flask 可以與您珠聯璧合。
默認情況下,Flask 不包含數據庫抽象層、表單驗證,或是其它任何已有多種庫可以勝任的功能。然而,Flask 支持用擴展來給應用添加這些功能,如同是 Flask 本身實現的一樣。眾多的擴展提供了數據庫集成、表單驗證、上傳處理、各種各樣的開放認證技術等功能。Flask 也許是“微小”的,但它已準備好在需求繁雜的生產環境中投入使用。
二、Flask快速使用
安裝Flask
pip install Flask快速使用
from flask import Flaskapp = Flask(__name__) # 類實例得到一個對象@app.route('/') # 注冊路由 def hello_world(): # put application's code herereturn 'Hello World!'if __name__ == '__main__':app.run() # 默認是host='127.0.0.1', port=5000端口'''這個時候訪問5000端口跟路徑就能看到 Hellow World了 '''三、Flask展示用戶信息案例
app.py
from flask import Flask, request, render_template, redirect, sessionapp = Flask(__name__) app.debug = True # print(app.config) # 拿到當前app配置 app.secret_key = 'asdadadadLIkeasda1*asd12(01231' # 如果需要使用到session需要配置密鑰否則報錯USERS = {1: {'name': 'Like', 'age': 21, 'gender': '男'},2: {'name': 'Lisa', 'age': 22, 'gender': '女'},3: {'name': 'Alice', 'age': 23, 'gender': '女'}, }@app.route('/login', methods=['GET', 'POST']) def login(): # put application's code hereif request.method == 'GET':return render_template('login.html') # 模版都需要寫在templates里面 可以通過settings修改名稱else:username = request.form.get('username') # Flask取數據從form里面獲取password = request.form.get('password')if username == 'Like' and password == '123':session['is_login'] = Truereturn redirect('/index')else:return render_template('login.html', errors='用戶名或密碼錯誤')@app.route('/index', methods=['GET']) def index():if session.get('is_login'):return render_template('index.html', **{'users': USERS})else:return redirect('/login')@app.route('/detail/<int:id>') def detail(id):if session.get('is_login'):user = USERS.get(id)return render_template('detail.html', **{'user': user})else:return redirect('/login')if __name__ == '__main__':app.run()"""總結:1.注冊路由:@app.route(" /detail/<int:id>" ,methods=['GET']) methods:允許的請求方式2.新手四件套:-返回模板:return render_template (' detail.html” , **{'user':user}) # Context跟Django不一樣-返回重定向:return redirect('/Login')-返回字符串:return '字符串'-返回json格式:return jsonify3. 使用cookie---就是session,全局的,導入使用即可,必須要指定秘鑰-放值:session[key] = value-取值:session.get('key')4.轉換器:@app.route('/detail/<int:id>'), 配合視圖函數寫法def detail(id)5.前端Post請求 提交數據 request.form6.模版語法:兼容Django的Dtl語法, 它可以使用 V. V[''] V.get() 取值"""login.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <form method="post"><p>用戶名: <input type="text" name="username"></p><p>密碼: <input type="password" name="password"></p><p>用戶名: <input type="submit" value="登錄"> <span>{{ errors }}</span></p> </form> </body> </html>index.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <table>{% for k,v in users.items() %}<tr><td>{{ k }}</td><td>{{ v.name }}</td><td>{{ v['name'] }}</td><td>{{ v.get('name') }}</td><td><a href="/detail/{{ k }}">查看詳細信息</a></td></tr>{% endfor %} </table> </body> </html>detail.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <h1>用戶名稱:{{ user.name }}</h1> {# 支持Django中的Dtl語法 #} <h1>用戶年齡:{{ user.age }}</h1> <h1>用戶性別:{{ user.gender }}</h1> </body> </html>四、Flask配置文件
Flask中的配置文件是一個flask.config.config對象(繼承字典)如果不配置的話是有默認配置的
{'DEBUG': get_debug_flag(default=False), 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'PRESERVE_CONTEXT_ON_EXCEPTION': None,'SECRET_KEY': None, 'PERMANENT_SESSION_LIFETIME': timedelta(days=31), 'USE_X_SENDFILE': False,'LOGGER_NAME': None,'LOGGER_HANDLER_POLICY': 'always','SERVER_NAME': None,'APPLICATION_ROOT': None,'SESSION_COOKIE_NAME': 'session','SESSION_COOKIE_DOMAIN': None,'SESSION_COOKIE_PATH': None,'SESSION_COOKIE_HTTPONLY': True,'SESSION_COOKIE_SECURE': False,'SESSION_REFRESH_EACH_REQUEST': True,'MAX_CONTENT_LENGTH': None,'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12),'TRAP_BAD_REQUEST_ERRORS': False,'TRAP_HTTP_EXCEPTIONS': False,'EXPLAIN_TEMPLATE_LOADING': False,'PREFERRED_URL_SCHEME': 'http','JSON_AS_ASCII': True,'JSON_SORT_KEYS': True,'JSONIFY_PRETTYPRINT_REGULAR': True,'JSONIFY_MIMETYPE': 'application/json','TEMPLATES_AUTO_RELOAD': None,}修改配置文件
app.config['DEBUG'] = True # 由于Config對象本質上是字典,所以還可以使用app.config.update(...) app.config.from_pyfile('python文件名稱') # 使用本地配置文件 app.config.from_envvar('環境變量名稱') # 使用環境變量里面的信息 app.config.from_json('json文件名稱') # 必須為Json格式 因為內部會執行json.loads app.config.from_mapping({'DEBUG': True}) # 字典格式 app.config.from_object('object / path') # python類或類的路徑五、路由系統
1)路由系統
路由的典型寫法
@app.route('/detail/<int:id>', methods=['GET', 'POST'], endpoint='detail') # int轉換器 """methods: 列表規定了請求方式 如果列表中沒有請求方式不被允許endpoint: 路由別名 如果不寫會被裝飾的函數名作為別名 """路由中的默認轉換器
DEFAULT_CONVERTERS = {'default': UnicodeConverter, # 默認'string': UnicodeConverter, # 字符串'any': AnyConverter, # 任何類型'path': PathConverter, # 路徑'int': IntegerConverter, # 數字'float': FloatConverter, # 小數'uuid': UUIDConverter, # asdad-asdda-asdaa }2)路由本質
1. decorator = app.route('/',methods=['GET','POST'],endpoint='n1') # 如果沒有傳endpoint,這個地方就是Nonedef route(self, rule, **options):# app對象 # rule= / # options = {methods=['GET','POST'], endpoint='n1'}def decorator(f):endpoint = options.pop('endpoint', None)self.add_url_rule(rule, endpoint, f, **options)# self是Flask的對象 app:rule路由 endpoint:別名,是None 其他的打散了傳入了(methods..)return freturn decorator2. @decoratordecorator(index)# 加了裝飾器最終,返回的還是index,只不過執行了 self.add_url_rule(rule, endpoint, f, **options)"""Flask類中的add_url_rule方法最終意思:rule就是裝飾器傳入的路徑與路由endpoint別名view_func視圖函數不加括號最終結論“現在不需要使用裝飾器來注冊路由”app.add_url_rule('/home', view_func=home, endpoint='home')...(最終的結果就像Django中的SimpleRouter自動生成路由 可以寫多個)"""3)Add_url_rule的參數
@app.route和app.add_url_rule參數:rule == urlview_func == 視圖函數名稱defaluts == None 默認值 需要穿值就是 defaluts = {'K': 'v'}endpoint == None 名稱 用于反向生成url methods = None 允許請求的方式strict_slashes = None 對url最后的/符號是否嚴格要求 # @app.route('/index', strict_slashes=False) 如果是True的話那就需要嚴格添加/否則匹配失敗redirect_to = None 重定向到指定地址# @app.route('/index/<int:id>', redirect_to='/home/<id>') 當訪問起那么這個路徑直接跳轉到后面這個路徑六、Flask的CBV
1)CBV的寫法
from flask import Flask from flask.views import MethodViewapp = Flask(__name__)# @app.route('/test', methods=['GET', 'POST']) class Test(MethodView):def get(self):return '我是Get請求'def post(self):return '我是Post請求'app.add_url_rule('/test', view_func=Test.as_view(name='test'))# app.add_url_rule('/login', view_func=Login.as_view(name='index'))if __name__ == '__main__':app.run()2)CBV添加裝飾器
class Test(MethodView):decorators = ['login', 'auth'] # 在類屬性中添加decorators屬性列表 是按照列表順序依次給每個方法添加裝飾器def get(self):return '我是Get請求''''首先會想我們裝飾器的原理@authdef view(): 本質就是 view = auth(view) 當作參數傳入返回函數看完源碼我們就知道了 是通過for循環的給視圖類添加裝飾器 '''3)as_view的執行流程
把源碼精簡一下def as_view(cls, name, *class_args, **class_kwargs):def view(**kwargs):return self.dispatch_request(**kwargs)return viewdef dispatch_request(self, **kwargs):meth = getattr(self, request.method.lower(), None)return meth(**kwargs) 請求來了,路由匹配成功,會執行as_view內的view() 也執行了類中的self.dispatch_request....這個就跟我們Django中的CBV一樣了然后看到self.dispatch_request中方法 ,在當前視圖類中反射,請求方式的小寫字符串(get,post),如果我們寫了這些方法 就會去執行。4)Login.as_view(name=‘index’) name到底有什么用?
先研究endpoint有什么用,正常的fbv,如果不寫endpoint會以函數名作為別名endpoint如何設置的?如果endpoint為None,它把函數名作為了endpointif endpoint is None:endpoint = _endpoint_from_view_func(view_func) # view_func.__name__options["endpoint"] = endpoint # 如果都是endpoint就會沖突Login.as_view(name='index'),name到底有啥用app.add_url_rule('/login', view_func=Login.as_view('login'))沒有傳endpoint,Login.as_view('login')是view函數的內存地址endpoint會以函數名作為endpoint的值,現在所有函數都是view,必須傳入name,來修改調view函數的名字如果傳了endpoint,別名以endpoint為主,如果不傳endpoint,別名以name為主app.add_url_rule('/login', view_func=Login.as_view(name='login'),endpoint='xxx')5)CBV中得methods作用
視圖類中有個屬性就是methods = ['GET', 'POST'] 用來控制允許的請求方式 寫了什么方法 就允許什么請求 若沒有寫則不能使用該方法七、模板語法
渲染變量
<table>{% for k,v in users.items() %}<tr><td>{{ k }}</td><td>{{ v.name }}</td><td>{{ v['name'] }}</td><td>{{ v.get('name') }}</td><td><a href="/detail/{{ k }}">查看詳細信息</a></td></tr>{% endfor %} </table>變量的循環
<body><h1>用戶列表</h1><table>{% for k,v in user_dict.items() %}<tr><td>{{k}}</td><td>{{v.name}}</td><td>{{v['name']}}</td><td>{{v.get('name')}}</td><td><a href="/detail/{{k}}">查看詳細</a></td></tr>{% endfor %}</table> </body>邏輯判斷
<body><h1>用戶列表</h1><table>{% if name %}<h1>Hello {{ name }}!</h1>{% else %}<h1>Hello World!</h1>{% endif %}</table> </body>比Django中多了可以加括號 執行函數 傳參數
from flask import Flask,render_template,Markup,jsonify,make_response app = Flask(__name__)def func1(arg):return Markup("<input type='text' value='%s' />" %(arg,)) @app.route('/') def index():return render_template('index.html',ff = func1)if __name__ == '__main__':app.run()index.html<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>{{ff('六五')}}{{ff('六五')|safe}}</body></html>總結
以上是生活随笔為你收集整理的Flask从入门到放弃(介绍、模版语法案例、配置文件、路由本质、CBV整体流程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Five reasons to embr
- 下一篇: 台湾大学林轩田机器学习技法课程学习笔记8