品優購專案
阿新 • • 發佈:2022-12-07
def index(): # 請求物件,是全域性的,需要匯入,這個全域性的request,在哪個檢視函式中,就是當次的request物件,不會亂 # request.method 提交的方法 print(request.method) # request.args get請求提及的資料 print(request.args) print(request.args.get('name')) # request.form post請求提交的資料 print(request.form)# request.values post和get提交的資料總和 print(request.values) # request.cookies 客戶端所帶的cookie print(request.cookies) # request.headers 請求頭 print(request.headers) print('------') # request.path 不帶域名,請求路徑 print(request.path) # request.full_path 不帶域名,帶引數的請求路徑 print(request.full_path) # request.script_root print('服務端:', request.script_root) # request.url 帶域名帶引數的請求路徑 print(request.url) # request.base_url 帶域名請求路徑 print(request.base_url) # request.url_root 域名 print(request.url_root) # request.host_url 域名print(request.host_url) # request.host 127.0.0.1:500 print(request.host) # request.files print(request.files) # obj = request.files['files'] # obj.save('./xx.jpg') print(request.data) # django的body return 'hellod'
@app.route('/',methods=['GET','POST']) def index(): # 1四件套 # -render_template # -redirect # -jsonify # -'' # 2寫入響應頭-->沒有響應物件,先做出一個響應物件 # from .wrappers import Response res='helloe' res=make_response(res) # 往Response的物件中,放入響應頭 res.headers['name']='lqz' # 3 寫入cookie # res.set_cookie('xx','xx') res.delete_cookie('xx') ''' key, 鍵 value=’’, 值 max_age=None, 超時時間 cookie需要延續的時間(以秒為單位)如果引數是\ None`` ,這個cookie會延續到瀏覽器關閉為止 expires=None, 超時時間(IE requires expires, so set it if hasn’t been already.) path=’/‘, Cookie生效的路徑,/ 表示根路徑,特殊的:根路徑的cookie可以被任何url的頁面訪問,瀏覽器只會把cookie回傳給帶有該路徑的頁面,這樣可以避免將cookie傳給站點中的其他的應用。 domain=None, Cookie生效的域名 你可用這個引數來構造一個跨站cookie。如, domain=”.example.com”所構造的cookie對下面這些站點都是可讀的:www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。如果該引數設定為 None ,cookie只能由設定它的站點讀取 secure=False, 瀏覽器將通過HTTPS來回傳cookie httponly=False 只能http協議傳輸,無法被JavaScript獲取(不是絕對,底層抓包可以獲取到也可以被覆蓋) ''' return res
# 前後端混合,cookie 是後端寫入的 - res.set_cookie('xx','xx') 混合都是這麼寫的,這樣寫了,瀏覽就會把cookie儲存到cookie中 -本質是後端把cookie放到響應頭中,瀏覽器讀到響應頭中有cookie,把cookie寫入到瀏覽器中 # 前後端分離後 -直接把客戶端要存到cookie中的資料,放到響應體中 -前端(瀏覽器,app,小程式),自己取出來,放到相應的位置 瀏覽器使用js自己寫入到cookie app 自己使用程式碼寫入到某個位置
2.1 session的使用
# 放值 檢視函式中 匯入全域性的session session['name']='bxf' # 取值 檢視函式中 匯入全域性的session print(session['name'])
# django 的這一套,都在 from django.contrib.sessions.middleware import SessionMiddleware # flask 在flask原始碼中 -請求來了,會執行 app() # 整個flask,從請求進來,到請求走的整個流程 def wsgi_app(self, environ, start_response): ctx = self.request_context(environ) try: try: ctx.push() # 它的原始碼 response = self.full_dispatch_request() except Exception as e: error = e response = self.handle_exception(e) except: error = sys.exc_info()[1] raise return response(environ, start_response) finally: ctx.pop(error) # ctx.push 的 373行左右 if self.session is None: session_interface = self.app.session_interface self.session = session_interface.open_session(self.app, self.request) if self.session is None: self.session = session_interface.make_null_session(self.app) # app.session_interface 就是Flask物件中有個session_interface物件 SecureCookieSessionInterface() -open_session:請求來了,從cookie中取出三段串,反序列化解密放到session中 -save_session:請求走了,把session字典中的值,序列化加密,放到cookie中 # open_session:請求來了執行 def open_session(self, app, request) : s = self.get_signing_serializer(app) if s is None: return None # val 就是取出的三段:eyJhZ2UiOiIxOSIsIm5hbWUiOiJscXoifQ.Y5ac9g.vOomQFqFuaqXWqRQhvSNyc61UIk val = request.cookies.get('session') if not val: return self.session_class() max_age = int(app.permanent_session_lifetime.total_seconds()) try: data = s.loads(val, max_age=max_age) return self.session_class(data) except BadSignature: return self.session_class() # 請求走了,執行save_session def save_session(self, app, session, response): name = self.get_cookie_name(app) domain = self.get_cookie_domain(app) path = self.get_cookie_path(app) secure = self.get_cookie_secure(app) samesite = self.get_cookie_samesite(app) httponly = self.get_cookie_httponly(app) if not session: # 如果檢視函式放了,不為空 session['name']='lqz' if session.modified: # response.delete_cookie( name, domain=domain, path=path, secure=secure, samesite=samesite, httponly=httponly, ) return if session.accessed: response.vary.add("Cookie") if not self.should_set_cookie(app, session): return expires = self.get_expiration_time(app, session) # 序列化---》加密了 val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore # 三段: response.set_cookie( name, # session val, # 三段: expires=expires, httponly=httponly, domain=domain, path=path, secure=secure, samesite=samesite, ) # 總結:session的執行流程 1 請求來的時候,會執行open_session--->取出cookie,判斷是否為空,如果不為空,把它反序列化,解密---》字典---》轉到session物件中----》檢視函式 2 請求走的時候,會執行save_session---->把session轉成字典----》序列化加密--》三段---》放到cookie中
# flash 翻譯過來叫閃現 # 作用: 訪問a頁面,出了錯,重定向到了b頁面,要在b頁面線上a頁面的錯誤資訊 在某個請求中放入值,另一個請求中取出,取出來後就沒了 # 使用 設定值: flash('不好意思,沒有許可權看') 可以用多次 取值:取出列表 get_flashed_messages() # 使用方式二:分類設定和獲取 設定值: flash('錢錢錢',category='lqz') flash('666',category='c1')') 可以用多次 取值:取出列表 errors = get_flashed_messages(category_filter=['lqz'])
# 非同步框架 FastAPi async def index(): print('sdfasd') a++ await xxx # io操作 async def goods(): pass # 框架之前的web框架,開啟程序,執行緒---》一條執行緒會執行多個協程函式----》協程函式中遇到io,讀到await關鍵字,就會切換到別的協程函式 # 一旦使用了非同步,以後所有的模組,都要是非同步 -pymysql :同步的 -redis :同步 -aiomysql:非同步 -aioredis:非同步 -在fastapi或sanic中,要操作mysql,redis要使用非同步的框架,否則效率更低 -django 3.x 以後頁支援async 關鍵字 -沒有一個特別好非同步的orm框架 -sqlalchemy在做 -tortoise-orm https://tortoise-orm.readthedocs.io/en/latest/index.html # aiomysql import asyncio import aiomysql loop = asyncio.get_event_loop() async def test_example(): conn = await aiomysql.connect(host='127.0.0.1', port=3306, user='root', password='', db='mysql', loop=loop) cur = await conn.cursor() await cur.execute("SELECT Host,User FROM user") print(cur.description) r = await cur.fetchall() print(r) await cur.close() conn.close() loop.run_until_complete(test_example()) # aioredis import aioredis import asyncio class Redis: _redis = None async def get_redis_pool(self, *args, **kwargs): if not self._redis: self._redis = await aioredis.create_redis_pool(*args, **kwargs) return self._redis async def close(self): if self._redis: self._redis.close() await self._redis.wait_closed() async def get_value(key): redis = Redis() r = await redis.get_redis_pool(('127.0.0.1', 6379), db=7, encoding='utf-8') value = await r.get(key) print(f'{key!r}: {value!r}') await redis.close() if __name__ == '__main__': asyncio.run(get_value('key')) # need python3.7
# 在請求進入檢視函式之前,執行一些程式碼 # 請求出了檢視函式以後,執行一些程式碼 # 類似於django的中介軟體完成的功能 # 7個裝飾器 # 1 before_request:在請求進檢視函式之前執行 多個的話,會從上往下,依次執行, django:process_request 如果返回四件套之一,就直接返回了 在這裡面,正常使用request物件 #2 after_request:在請求從檢視函式走之後執行 多個的話,會從下往上,依次執行, django:process_response一樣 要有引數,和返回值,引數就是response物件,返回值也必須是resposne物件 session,request 照常使用 向響應頭寫東西?向cookie中寫東西 # 3 before_first_request:專案啟動後,第一次訪問會執行,以後再也不執行了 可以做一些初始化的操作 # 4 teardown_request:每一個請求之後繫結一個函式,即使遇到了異常,每個請求走,都會執行,記錄錯誤日誌 @app.teardown_request def tear_down(e): print(e) # 如果有異常,這是異常物件 print('我執行了') #5 errorhandler路徑不存在時404,伺服器內部錯誤500 # @app.errorhandler(404) # def error_404(arg): # print('404會執行我') # # return "404錯誤了" # return render_template('404.html') @app.errorhandler(500) # debug為False請情況下才能看到 def error_500(arg): print('500會執行我') return "伺服器內部錯誤" # 6 template_global 標籤 ,在模板中用 {{sb(1,2)}} @app.template_global() def sb(a1, a2): return a1 + a2 # 7 template_filter過濾器 在模板中用 {{10|db(1,2)}} @app.template_filter() def db(a1, a2, a3): return a1 + a2 + a3
# blueprint:對目錄進行劃分,因為之前所有程式碼都寫在一個py檔案中,後期肯定要分到多個檔案中 # 藍圖就是為了劃分目錄的 # 使用步驟: -1 在不同的view的py檔案中,定義藍圖 -2 使用app物件,註冊藍圖 -3 使用藍圖,註冊路由,註冊請求擴充套件 # 不用藍圖劃分目錄 # 目錄結構 flask_blueprint -static # 靜態檔案存放位置 -templates # 模板存放位置 -user.html # 使用者html頁面 -views # 檢視函式的py檔案 -__init__.py # 裡面定義了Flask的app物件 goods.py # 商品相關檢視 user.py # 使用者相關檢視 app.py #啟動檔案 # 藍圖小型專案 flask_blueprint_little # 專案名 -src # 專案程式碼所在路徑 -__init__.py # app物件建立的地方 -templates # 模板 -user.html -static # 靜態檔案 -views # 檢視函式存放位置 -user.py # 使用者相關檢視 -order.py # 訂單相關檢視 -manage.py # 啟動檔案 # 大型專案 flask_blurprint_big # 專案名字 -src # 專案程式碼所在位置 -__init__.py # src的init,falsk,app例項化 -settings.py # 配置檔案 -admin # 類似於django的admin app -__init__.py # 藍圖初始化 -template # 模板 -backend.html -static # 靜態檔案 -xx.jpg -views.py # 檢視層 -models.py # models層,後期咱們表模型 -api -__init__.py -template -static -models.py -views.py -manage.py # 啟動檔案