內容回顧: 1. git的做用? 2. git命令? git init git add git status git commit git log git reflog git reset --hard git checkout 3. 路飛表結構: - 課程(13表) - 課程大類 - 課程子類 - 學位課 - 講師 - 獎學金 - 專題課(學位課模塊表) - 價格策略(contenttype) - 課程詳細(o2o -> 水平分表) - 常見問題 - 課程大綱 - 章節 - 課時 - 做業 - 深科技(4+2) - 用戶表 - 用戶token - 文章來源 - 文章表 - 通用評論表 - 通用收藏表 4. 談談你對 django rest framework框架的認識? - 路由, - 能夠經過as_view傳參數,根據請求方式不一樣執行相應的方法 - 能夠在url中設置一個結尾,相似於: .json - 視圖, - 幫助開發者提供了一些類,並在類中提供了多個方法以供咱們使用。 - 版本, - 在url中設置version參數,用戶請求時候傳入參數。在request.version中獲取版本,根據版本不一樣作不一樣處理 - 認證, - 寫一個類並註冊到認證類,在類的的authticate方法中編寫認證邏輯。 - 認證成功(user,auth) - raise AuthticateFaild(....) - None - 權限 - 寫一個類並註冊到權限類,在類的的has_permission方法中編寫認證邏輯。 - True - False - 頻率限制 - 寫一個類並註冊到頻率類,在類的的 allow_request/wait 方法中編寫認證邏輯。 allow_request - True - False 若是返回False,那麼就要執行wait - 解析器, - 根據ContentType請求頭,選擇不一樣解析器對 請求體中的數據進行解析。 POST /index/ http1.1.\r\nhost:11.11.11.11\r\nContent-Type:url-formendo.... \r\n\r\nuser=alex&age=123 POST /index/ http1.1.\r\nhost:11.11.11.11\r\nContent-Type:application/json\r\n\r\n{....} - 分頁 - 對從數據庫中獲取到的數據進行分頁處理: SQL -> limit offset - 根據頁碼:http://www.luffycity.com/api/v1/student/?page=1&size=10 - 根據索引:http://www.luffycity.com/api/v1/student/?offset=60&limit=10 - 根據加密:http://www.luffycity.com/api/v1/student/?page=erd8 贈送:頁碼越大速度越慢,爲何以及如何解決? 緣由:頁碼越大向後須要掃描的行數越多,由於每次都是從0開始掃描。 解決: - 限制顯示的頁數 - 記錄當前頁數據ID最大值和最小值,再次分頁時,根據ID現行篩選,而後再分頁。 - 序列化 - 對queryset序列化以及對請求數據格式校驗。 - 渲染器 - 根據URL中傳入的後綴,決定在數據如何渲染到到頁面上。 今日內容: - git - redis 內容詳細: 1. git,小東北創業史。 第一階段:在沙河的日子 第二階段:開發直播功能,開發過程當中臨時須要修復bug或臨時新功能到來。 方式一: git stash git stash pop git stash 將當前工做區全部修改過的內容存儲到「某個地方」,將工做區還原到當前版本未修改過的狀態 git stash list 查看「某個地方」存儲的全部記錄 git stash clear 清空「某個地方」 git stash pop 將第一個記錄從「某個地方」從新拿到工做區(可能有衝突) git stash apply 編號, 將指定編號記錄從「某個地方」從新拿到工做區(可能有衝突) git stash drop 編號,刪除指定編號的記錄 git stash做用,幫助咱們暫時存儲已經開發一些功能的代碼,繼續作其餘事情,作完以後,再回來繼續開發 方式二: git branch git branch dev git branch bug git branch -d bug git checkout dev git merge bug 面試題:若是代碼出現bug,大家是如何解決? 建立一個bug分支,而後進行bug處理,處理完畢後,合併到master分支。 刪除bug分支 回到dev分支繼續開發。 第三階段:在三里屯買了一層樓。 須要一個代碼託管的網站:github、Bitbucket、碼雲 本身建立代碼託管的網站:gitlab 註冊帳號: 用戶名:郵箱 密碼:admin123 命令: git remote add origin ......... git push origin dev git clone https://github.com/WuPeiqi/dbhot.git git pull origin dev git fetch origin dev git merge origin/dev 改: git rebase origin/dev git pull origin master git fetch origin master git merge origin/master
git pull origin master --allow-unrelated-histories
git rebase的做用? 保持提交記錄的整潔。 2. redis mysql是一個軟件,幫助開發者對一臺機器的硬盤進行操做。 redis是一個軟件,幫助開發者對一臺機器的內存進行操做。 關鍵字: 緩存,優先去redis中獲取,若是沒有就是數據庫。 安裝: - redis軟件 - yum install redis redis-server /etc/redis.conf - wget http://download.redis.io/releases/redis-3.0.6.tar.gz tar xzf redis-3.0.6.tar.gz cd redis-3.0.6 make /src/redis-server redis.conf 默認端口:6379 配置文件: bind 0.0.0.0 port 6379 requirepass dskjfsdf - python鏈接redis的模塊 pip3 install redis 基本使用: a. import redis # 建立鏈接 # conn = redis.Redis(host='47.94.172.250',port=6379,password='luffy1234') # conn.set('x1','wanghuaqiang',ex=5) # val = conn.get('x1') # print(val) b. # 鏈接池 # import redis # # pool = redis.ConnectionPool(host='10.211.55.4', port=6379,password='luffy1234',max_connections=1000) # conn = redis.Redis(connection_pool=pool) # # conn.set('foo', 'Bar') 鏈接池注意:鏈接池只建立一次 總結: 1. git+github 2. redis
s9day110 內容回顧: 1. git開發時,出bug如何結局? 2. git rebase的做用? 3. git 命令? 4. redis是什麼? 用於操做內存的軟件。 - 能夠作持久化: - AOF - RDB - 至關因而大字典 - 單進程單線程 5. 使用鏈接池 本質,維護一個已經和服務端鏈接成功的socket。 之後再次發送數據時,直接獲取一個socket,直接send數據。 6. 路飛表結果 - 課程 - 大類 - 子類 - 學位課 - 獎學金 - 老師 - 專題課 - 課程詳細 - 大綱 - 做業 - 章節 - 課時 - 價格策略 - 深科技 - 文章來源 - 文章 - 用戶 - token - 評論 - 收藏 7. 支付寶支付 - 加密方式:rsa - 公鑰私鑰: - 商戶私鑰 - 支付寶公鑰 - 支付成功後,斷電宕機 - 成功:return HttpResponse('success') 8. rest framework框架 9. 數據庫頁數越大速度越慢。 - 限制頁數 - 記錄當前頁最大ID、最小ID - 錯誤答案: - 掃描索引表 - 再去數據庫表中獲取數據 今日內容: 1. git 2. redis 3. 改代碼 內容詳細: 1. git 第四階段: 多人協同開發 1. 容許他人操做程序 - 合做者 - 建立組織 2. 分支 - master - dev - xdb - zhh 3. 規則 - 一塊兒合併 - 合併時間:1/2 問題: $ git push origin dev To https://github.com/WuPeiqi/dbhot.git ! [rejected] dev -> dev (fetch first) error: failed to push some refs to 'https://github.com/WuPeiqi/dbhot.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. 4. 作代碼review 如何作代碼review? - 建立review分支: 誰來鎖代碼review? - 組長 - 帶你的人 第五階段:給別人代碼貢獻力量 問題: 若是你要在github上給別人代碼添加功能? fork pull request 其餘: a. 不用反覆輸入用戶名密碼登陸 Https: https://用戶名:密碼@github.com/WuPeiqi/dbhot.git git remote add origin https://用戶名:密碼@github.com/WuPeiqi/dbhot.git SSH: git@github.com:WuPeiqi/dbhot.git b. .gitignore文件 c. 版本 git tag -a v1.0 -m '版本介紹' 本地建立Tag git show v1.0 查看 git tags -n 查看本地Tag git tag -l 'v1.4.2.*' 查看本地Tag,模糊匹配 git tag -d v1.0 刪除Tag git push origin :refs/tags/v0.2 更新遠程tag git checkout v.10 切換tag git fetch origin tag V1.2 git push origin --tags git pull origin --tags git clone -b v1.0 https://github.com/WuPeiqi/dbhot.git 要求: 1. 組長建立項目(把本身的路飛學城api):master/dev 2. 組長邀請組員盡力啊 3. 組員: - 建立本身分支 - 修改代碼,去提交。 2. redis 特色: a. 持久化 b. 單進程、單線程 c. 5大數據類型 redis={ k1:'123', 字符串 k2:[1,2,3,4,4,2,1], 列表 k3:{1,2,3,4}, 集合 k4:{name:123,age:666}, 字典 k5:{('alex',60),('eva-j',80),('rt',70),},有序集合 } 使用字典: - 基本操做 - 慎重使用hgetall, 優先使用 hscan_iter - 計數器 注意事項:redis操做時,只有第一層value支持:list,dict .... 應用(django): 1. 自定義使用redis 2. 使用第三方組件 pip3 install django-redis 配置: CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100} # "PASSWORD": "密碼", } } } 使用: import redis from django.shortcuts import render,HttpResponse from django_redis import get_redis_connection def index(request): conn = get_redis_connection("default") return HttpResponse('設置成功') def order(request): conn = get_redis_connection("back") return HttpResponse('獲取成功') 高級使用: 1. 全站緩存 2. 單視圖 3. 局部頁面 補充:rest framework框架訪問頻率限制推薦放到 redis/memecached
s9day111 內容迴歸: 1. django rest framework 2. git協同開發 a. 怎麼經過git作得協同開發? b. 是否作代碼review? c. 開發過程當中出現bug如何作? d. git rebase做用? e. 給別人開源代碼貢獻力量。 f. 使用的github、gitlab ? PS:隱藏明感信息 3. orm操做 - select_related,連表操做,至關於主動作join - prefeth_related,屢次單表操做,先查詢想要的數據,而後構造條件,如:id=[1,2,3],再次查詢其餘表根據id作條件。 - only - defer - F - Q - 經過ORM寫偏原生SQL: - extra Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,)) Entry.objects.extra(where=['headline=%s'], params=['Lennon']) Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"]) Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid']) - raw # 執行原生SQL models.UserInfo.objects.raw('select * from userinfo') # 若是SQL是其餘表時,必須將名字設置爲當前UserInfo對象的主鍵列名 models.UserInfo.objects.raw('select id as nid from 其餘表') # 爲原生SQL設置參數 models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12,]) name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'} Person.objects.raw('SELECT * FROM some_other_table', translations=name_map) - 原生SQL from django.db import connection, connections cursor = connection.cursor() # cursor = connections['default'].cursor() cursor.execute("""SELECT * from auth_user where id = %s""", [1]) row = cursor.fetchone() # fetchall()/fetchmany(..) PS: 選擇數據庫 queryset = models.Course.objects.using('default').all() 4. redis - 是否能夠持久化?AOF、RDB - 單進程、單線程 - 5大數據類型 - 字典操做: - scan_iter 5. 跨域 - JSONP - CORS 6. Http協議 & django 生命週期 & wsgi & FBV、CBV 7. 中間件 8. restful 規範 9. 支付 - rsa - 商戶私鑰+支付寶公鑰 - 精度 -宕機 10. 原生Ajax - XMLHttpRequest 今日內容: - redis - 列表 - 微信消息推送 - 支付相關表結構 內容詳細: - redis - 左右操做 - 阻塞 - 經過yield建立一個生成器完成一點一點獲取(經過字典操做的源碼來的靈感) def list_iter(key,count=100): index = 0 while True: data_list = conn.lrange('k1', index, index+count-1) if not data_list: return index += count for item in data_list: yield item PS: 隊列:先進先出 棧:後進先出 - 事務+一次發送多個命令: conn = redis.Redis(host='47.94.172.250',port=6379,password='Luffy!4321') pipe = conn.pipeline(transaction=True) pipe.multi() pipe.set('k2','123') pipe.hset('k3','n1',666) pipe.lpush('k4','laonanhai') pipe.execute() - 微信消息推送 - 公衆號 - 已認證公衆號 - 服務號 - 已認證服務號 - 企業號 基於:微信認證服務號 主動推送微信消息。 前提:關注服務號 環境:沙箱環境 總結: 1. 註冊帳號 appID:wx89085e915d351cae appsecret:64f87abfc664f1d4f11d0ac98b24c42d 網頁受權獲取用戶基本信息:47.98.134.86 或 域名 2. 關注公衆號(已認證的服務號) 3. 生成二維碼,用戶掃描; 將用戶信息發送給微信,微信再將數據發送給設置redirect_uri地址(md5值) 4. 回調地址:47.98.134.86/callback/ - 受權 - 用戶md5 - 獲取wx_id 在數據庫中更新設置:wx_id 5. 發送消息(模板消息) - wx_id - access_token(2小時有效期) - 支付相關: 1. 加入購物車,保存到redis 理由: a. 臨時狀態 b. 修改購物信息 結構: redis->{ shopping_car:{ 用戶ID:{ 課程1:{ title:'金融量化分析入門', img:'/xx/xx/xx.png', policy:{ 10: {'name':'有效期1個月','price':599}, 11: {'name':'有效期3個月','price':1599}, 13: {'name':'有效期6個月','price':2599}, }, default_policy:12 }, 課程2:{ title:'金融量化分析入門', img:'/xx/xx/xx.png', policy:{ 10: {'name':'有效期1個月','price':599}, 11: {'name':'有效期3個月','price':1599}, 13: {'name':'有效期6個月','price':2599}, }, default_policy:10 } }, 用戶ID:{...}, } } POST請求:購物車中添加一條數據 請求體: { courseid:1, policy_id:10 } 後臺: 檢驗當前課程是否有此價格策略,合法:將數據構造字典,再添加到redis GET請求:查看本身購物車中的全部數據 獲取當前登陸用戶ID,根據用戶ID去redis的購物車中獲取數據。 DELETE請求:刪除購物車中的數據 請求體: { course_ids:[1,2] } PUT/PATCH請求:更新價格策略 請求體: { courseid:1, policy_id:13 } 注意:不要寫vue、不要寫vue、不要寫vue 2. 結算中心 3. 去支付 總結: 1. redis列表操做 - 先後均可以 - 等 - yield - pipeline 2. 微信消息推送 - 已認證服務號 - 模板消息 - 生成二維碼 3. 路飛購物車 - 爲何使用redis? - 字典是如何構造? 做業: 1. django orm操做 2. 購物車 - django-redis組件
s9day112 內容回顧: 1. redis列表 - 左右 - hang住 - 經過yield構造生成器 寫一個棧:寫一個類實現後進先出的結構。 class FooStack(object): def push(self): pass def pop(self): pass 2. redis字典 - hscan_iter 3. 事務 4. 鏈接池 5. 單進程單線程 6. 持久化: - AOF - RDB 7. 微信消息推送 - 自動獲取 wx_id - 根據用戶 wx_id向用戶推送消息 - 已認證的服務號 8. 支付寶支付 - 加密:RSA - 祕鑰:商戶私鑰+支付寶公鑰 - 宕機:重發 - 精度:1.11 9. ORM - only - defer - select_related - prefetch_related - 偏原生 - raw - extra - connection - .using('default') - .exclude(id=5) 今日內容: - 加入購物車 做業: - 結算中心 內容詳細: - 加入購物車 1. 配置 CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://140.143.227.206:6379", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100}, "PASSWORD": "1234", } } } 2. 路由 3. 認證組件 4. 業務(合法性) - 增 - 刪 - 改 - 查 做業: a. 實現購物車邏輯 b. 結算中心 1.購物車(能夠選擇價格策略) { luffy_shopping_car_6_11:{ 'title':'21天入門到放棄', 'src':'xxx.png', 'policy':{ 1:{id:'xx'.....}, 2:{id:'xx'.....}, 3:{id:'xx'.....}, 4:{id:'xx'.....}, }, 'default_policy':3 }, luffy_shopping_car_6_13:{ ... } } 2.結算(能夠選擇優惠券) a. POST請求,去結算 請求體: { courseids:[1,2] } 業務處理: 1. 檢測課程ID是否已經加入到購物車 2. 獲取指訂價格策略信息 3. 獲取優惠券信息 4. 構造結構放入redis b. GET請求,獲取結算中心數據 業務處理: 1. 獲取結算中內心的課程信息(綁定課程優惠券) 2. 獲取全局優惠券 c. PATCH請求,選擇優惠券 請求體: { courseid:0 couponid:12 } 業務處理: 1. 校驗結算中心是否存在該課程 2. 校驗優惠券是否可用 注意: 1. 優惠券狀態 2. 優惠券使用時間
s9day113 內容回顧: 1. 路飛學城的購物車如何實現? 2. 商品是否有個數? - 價格策略(用事件來類比個數) - 購買以後就開始計時 3. 購物車在redis的結構? 4. 購物車購買數量有限制嗎? .keys('xxxxx') 5. 購物車是否設置超時時間? .conn.expire("shopping_car_1_1" ,60*30) 方案:購買課程個數限制(200個) 6. 爲何把購物車信息放入redis? - 臨時狀態 - 頻繁修改的話,速度快。 7. 具體購物車的邏輯? 添加: 1. 用戶選擇:課程、價格策略,提交 2. 獲取課程、價格策略進行合法性校驗(數據庫查詢) 3. 數據獲取,構造結構: { shopping_car_用戶ID_課程ID:{ title:"...", img:'xxx', policy:{ ... } } } 4. 將數據以字典的形式保存到redis中。 修改: 1. 用戶選擇:課程、價格策略,提交 2. 獲取課程、價格策略進行合法性校驗(redis查詢) 3. 更新價格策略 刪除: 1. 用戶選擇:課程提交 2. 獲取課程合法性校驗(redis查詢) 3. 刪除 查看: 1. 構造Key shopping_car_用戶ID_* 2. scan_iter 8. 原則: - 簡答邏輯先處理 - try - 細粒度異常+自定義異常 - 導入模塊 - 內置 - 框架 - 自定義 - 註釋 - 文件 - 類 - 函數 - 文件名、類、函數、project - 對功能進行分類 - 減小代碼層級 - BaseResponse 今日內容: - 結算中心 - 去支付 內容詳細: 1. 結算中心 a. 添加到結算中心: 請求:POST 數據: { courseids:[1,2] } Q補充: con = { "id":1, "age__gt":9, "name__lt": 8 "name__lt": 8 } # 構造AND models.User.objects.filter(**con) # 構造複雜(條件寫死) con = Q(Q(account=request.auth.user) & Q(status=0)) | Q(coupon__valid_begin_date__lte=ctime) models.User.objects.filter(con) # 構造負責(條件動態) q1 = Q() q1.connector = 'OR' for k,v in con.items(): q1.children.append((k,v,)) models.User.objects.filter(q1) 結算數據及目標: payment_dict = { '2': { course_id:2, 'title': 'CRM客戶關係管理系統實戰開發-專題', 'img': 'CRM.jpg', 'policy_id': '4', 'coupon': {}, 'default_coupon': 0, 'period': 210, 'period_display': '12個月', 'price': 122.0}, '1': { course_id:2, 'title': '爬蟲開發-專題', 'img': '爬蟲開發-專題.jpg', 'policy_id': '2', 'coupon': { 4: {'coupon_type': 0, 'coupon_display': '立減券', 'money_equivalent_value': 40}, 6: {'coupon_type': 1, 'coupon_display': '滿減券', 'money_equivalent_value': 60, 'minimum_consume': 100} }, 'default_coupon': 0, 'period': 60, 'period_display': '2個月', 'price': 599.0} } global_coupon_dict = { 'coupon': { 2: {'coupon_type': 1, 'coupon_display': '滿減券', 'money_equivalent_value': 200, 'minimum_consume': 500} }, 'default_coupon': 0 } ========================================= redis ============================================== redis = { payment_1_2:{ course_id:2, 'title': 'CRM客戶關係管理系統實戰開發-專題', 'img': 'CRM.jpg', 'policy_id': '4', 'coupon': {}, 'default_coupon': 0, 'period': 210, 'period_display': '12個月', 'price': 122.0}, }, payment_1_1:{ course_id:1, 'title': '爬蟲開發-專題', 'img': '爬蟲開發-專題.jpg', 'policy_id': '2', 'coupon': { 4: {'coupon_type': 0, 'coupon_display': '立減券', 'money_equivalent_value': 40}, 6: {'coupon_type': 1, 'coupon_display': '滿減券', 'money_equivalent_value': 60, 'minimum_consume': 100} }, 'default_coupon': 0, 'period': 60, 'period_display': '2個月', 'price': 599.0} }, payment_global_coupon_1:{ 'coupon': { 2: {'coupon_type': 1, 'coupon_display': '滿減券', 'money_equivalent_value': 200, 'minimum_consume': 500} }, 'default_coupon': 0 } }
s9day114 內容回顧: 1. 爲何要開發「學城」? - 提升在線 完課率(學成率)。 - 具體: - 購買時間週期 - 闖關式學習 - 考覈 - 導師篩選 - 導師監督(跟進記錄) - 答疑時間(12小時) - 獎懲措施 - 時間 - 做業 2. 開發週期和團隊? 團隊: - 開發 - 導師後臺,stark組件+rbac : 1人 - 管理後臺,stark組件+rbac : 1人 - 主站 - vue.js 1人 - api 村長+1/2文州+1/2Alex+其餘 + 村長 - 運維(1人) - 測試(1人) - 產品經理(1人) - UI設計(1人) - 運營(1人) - 銷售(4人) - 全職導師(2人) - 簽約講師(...) 週期: - 7月份 - 11月份上線 - 11月份~次年5月份: 修Bug,活動支持,廣告。。。 - 6月份:開發題庫系統 3. 購買流程 - 加入購物車 - 去結算 - 去支付 今日內容: - 去支付 - Flask - 基礎 - 第三方組件 - 上下文管理聊源碼 內容詳細: 1. 去支付(面向專題課) POST請求: URL: https://www.luffycity.com/course/order/?token=123879shdfkjshdf123 請求體: { balance:1000, money:900 } 業務處理: ... 2. Flask - pip3 install flask - 短小精悍、可擴展強 的一個Web框架。 注意:上下文管理機制 - 依賴wsgi:werkzurg - 學習werkzurg: 示例一: from werkzeug.wrappers import Request, Response from werkzeug.serving import run_simple def run(environ,start_response): return [b"asdfasdf"] if __name__ == '__main__': run_simple('localhost', 4000, run) 示例二: from werkzeug.wrappers import Request, Response @Request.application def hello(request): return Response('Hello World!') if __name__ == '__main__': from werkzeug.serving import run_simple run_simple('localhost', 4000, hello) - 學習Flask 做業: """ 1. 獲取用戶提交數據 { balance:1000, money:900 } balance = request.data.get("balance") money = request.data.get("money") 2. 數據驗證 - 大於等於0 - 我的帳戶是否有1000貝里 if user.auth.user.balance < balance: 帳戶貝里餘額不足 優惠券ID_LIST = [1,3,4] 總價 實際支付 3. 去結算中獲取課程信息 for course_dict in redis的結算中獲取: # 獲取課程ID # 根據course_id去數據庫檢查狀態 # 獲取價格策略 # 根據policy_id去數據庫檢查是否還依然存在 # 獲取使用優惠券ID # 根據優惠券ID檢查優惠券是否過時 # 獲取原價+獲取優惠券類型 - 立減 0 = 獲取原價 - 優惠券金額 或 折後價格 = 獲取原價 - 優惠券金額 - 滿減:是否知足限制 折後價格 = 獲取原價 - 優惠券金額 - 折扣: 折後價格 = 獲取原價 * 80 / 100 4. 全站優惠券 - 去數據庫校驗全站優惠券的合法性 - 應用優惠券: - 立減 0 = 實際支付 - 優惠券金額 或 折後價格 =實際支付 - 優惠券金額 - 滿減:是否知足限制 折後價格 = 實際支付 - 優惠券金額 - 折扣: 折後價格 = 實際支付 * 80 / 100 - 實際支付 5. 貝里抵扣 6. 總金額校驗 實際支付 - 貝里 = money:900 7. 爲當前課程生成訂單 - 訂單表建立一條數據 Order - 訂單詳細表建立一條數據 OrderDetail EnrolledCourse - 訂單詳細表建立一條數據 OrderDetail EnrolledCourse - 訂單詳細表建立一條數據 OrderDetail EnrolledCourse - 若是有貝里支付 - 貝里金額扣除 Account - 交易記錄 TransactionRecord - 優惠券狀態更新 CouponRecord 注意: 若是支付寶支付金額0, 表示訂單狀態:已支付 若是支付寶支付金額110,表示訂單狀態:未支付 - 生成URL(含訂單號) - 回調函數:更新訂單狀態 """
s9day115 Flask基礎 回顧: 1.談談你對django和flask的認識。 2.flask和django最大的不一樣點:request/session 3.flask知識點 - 模板+靜態文件,app= Flask(__name__,....) - 路由 @app.route('/index',methods=["GET"]) - 請求 request.form request.args request.method - 響應 "" render redirect - session session['xx'] = 123 session.get('xx') 4. 路飛總共有幾個項目 - 管理後臺 - 導師後臺 - 主站 5. 路飛主站業務 - 課程 - 課程列表 - 課程詳細 - 大綱、導師、推薦課程 - 價格策略 - 章節和課時 - 常見問題 - 深科技 - 文章列表 - 文章詳細 - 收藏 - 評論 - 點贊 - 支付 - 購物車(4) - 結算中心(3) - 當即支付(1) 知識點: - redis - 支付寶 - 消息推送 - 構建數據結構 - 優惠券+貝里+支付寶 - 我的中心 - 課程中心 6. 播放視頻:CC視頻 - 加密 - 非加密 今日內容: 1. 配置文件 2. 路由系統 3. 視圖 4. 請求相關 5. 響應 6. 模板渲染 7. session 8. 閃現 9. 中間件 10. 藍圖(blueprint) 11. 特殊裝飾器 內容詳細: 知識點: - 給你一個路徑 「settings.Foo」,能夠找到類並獲取去其中的大寫的靜態字段。 settings.py class Foo: DEBUG = True TEST = True xx.py import importlib path = "settings.Foo" p,c = path.rsplit('.',maxsplit=1) m = importlib.import_module(p) cls = getattr(m,c) # 若是找到這個類? for key in dir(cls): if key.isupper(): print(key,getattr(cls,key)) 1. 配置文件 app.config.from_object("settings.DevelopmentConfig") class Config(object): DEBUG = False TESTING = False DATABASE_URI = 'sqlite://:memory:' class ProductionConfig(Config): DATABASE_URI = 'mysql://user@localhost/foo' class DevelopmentConfig(Config): DEBUG = True class TestingConfig(Config): TESTING = True 2. 路由系統 - endpoint,反向生成URL,默認函數名 - url_for('endpoint') / url_for("index",nid=777) - 動態路由: @app.route('/index/<int:nid>',methods=['GET','POST']) def index(nid): print(nid) return "Index" 3. FBV 4. 請求相關 # 請求相關信息 # request.method # request.args # request.form # request.values # request.cookies # request.headers # request.path # request.full_path # request.script_root # request.url # request.base_url # request.url_root # request.host_url # request.host # request.files # obj = request.files['the_file_name'] # obj.save('/var/www/uploads/' + secure_filename(f.filename)) 5. 響應: 響應體: return 「asdf」 return jsonify({'k1':'v1'}) return render_template('xxx.html') return redirect() 定製響應頭: obj = make_response("asdf") obj.headers['xxxxxxx'] = '123' obj.set_cookie('key', 'value') return obj 示例程序:學生管理 版本一: @app.route('/index') def index(): if not session.get('user'): return redirect(url_for('login')) return render_template('index.html',stu_dic=STUDENT_DICT) 版本二: import functools def auth(func): @functools.wraps(func) def inner(*args,**kwargs): if not session.get('user'): return redirect(url_for('login')) ret = func(*args,**kwargs) return ret return inner @app.route('/index') @auth def index(): return render_template('index.html',stu_dic=STUDENT_DICT) 應用場景:比較少的函數中須要額外添加功能。 版本三:before_request @app.before_request def xxxxxx(): if request.path == '/login': return None if session.get('user'): return None return redirect('/login') 6. 模板渲染 - 基本數據類型:能夠執行python語法,如:dict.get() list['xx'] - 傳入函數 - django,自動執行 - flask,不自動執行 - 全局定義函數 @app.template_global() def sb(a1, a2): # {{sb(1,9)}} return a1 + a2 @app.template_filter() def db(a1, a2, a3): # {{ 1|db(2,3) }} return a1 + a2 + a3 - 模板繼承 layout.html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>模板</h1> {% block content %}{% endblock %} </body> </html> tpl.html {% extends "layout.html"%} {% block content %} {{users.0}} {% endblock %} - include {% include "form.html" %} form.html <form> asdfasdf asdfasdf asdf asdf </form> - 宏 {% macro ccccc(name, type='text', value='') %} <h1>宏</h1> <input type="{{ type }}" name="{{ name }}" value="{{ value }}"> <input type="submit" value="提交"> {% endmacro %} {{ ccccc('n1') }} {{ ccccc('n2') }} - 安全 - 前端: {{u|safe}} - 前端: MarkUp("asdf") 7. session 當請求剛到來:flask讀取cookie中session對應的值:eyJrMiI6NDU2LCJ1c2VyIjoib2xkYm95,將該值解密並反序列化成字典,放入內存以便視圖函數使用。 視圖函數: @app.route('/ses') def ses(): session['k1'] = 123 session['k2'] = 456 del session['k1'] return "Session" session['xxx'] = 123 session['xxx'] 當請求結束時,flask會讀取內存中字典的值,進行序列化+加密,寫入到用戶cookie中。 8. 閃現,在session中存儲一個數據,讀取時經過pop將數據移除。 from flask import Flask,flash,get_flashed_messages @app.route('/page1') def page1(): flash('臨時數據存儲','error') flash('sdfsdf234234','error') flash('adasdfasdf','info') return "Session" @app.route('/page2') def page2(): print(get_flashed_messages(category_filter=['error'])) return "Session" 9. 中間件 - call方法何時出發? - 用戶發起請求時,才執行。 - 任務:在執行call方法以前,作一個操做,call方法執行以後作一個操做。 class Middleware(object): def __init__(self,old): self.old = old def __call__(self, *args, **kwargs): ret = self.old(*args, **kwargs) return ret if __name__ == '__main__': app.wsgi_app = Middleware(app.wsgi_app) app.run() 10. 特殊裝飾器 1. before_request 2. after_request 示例: from flask import Flask app = Flask(__name__) @app.before_request def x1(): print('before:x1') return '滾' @app.before_request def xx1(): print('before:xx1') @app.after_request def x2(response): print('after:x2') return response @app.after_request def xx2(response): print('after:xx2') return response @app.route('/index') def index(): print('index') return "Index" @app.route('/order') def order(): print('order') return "order" if __name__ == '__main__': app.run() 3. before_first_request from flask import Flask app = Flask(__name__) @app.before_first_request def x1(): print('123123') @app.route('/index') def index(): print('index') return "Index" @app.route('/order') def order(): print('order') return "order" if __name__ == '__main__': app.run() 4. template_global 5. template_filter 6. errorhandler @app.errorhandler(404) def not_found(arg): print(arg) return "沒找到" 總結: - 配置文件 - 路由 - 視圖:FBV - 請求 - 響應 obj = make_response("adfasdf") obj.headers['x'] = asdfasdf return obj - 模板 - session - flash - 中間件 - 特殊裝飾器