python-django框架-電商項目-訂單模塊開發_20191125

python-django框架-電商項目-訂單模塊開發前端

 

提交訂單頁面:python

  • 在購物車中點擊提交訂單,就應該到達提交訂單頁面了,
  • 顯示:
  • 1,收穫地址,
  • 2,支付方式
  • 3,用戶購買的商品信息,數量,小計,
  • 4,總金額,運費,實際付多少,
  • 5,提交訂單按鈕,
  • 點擊提交按鈕,須要傳遞什麼?
  • 注意:價格這個是給用戶看的,不要傳到後臺,傳了後端也不用,
  • 商品的id要傳過去,另外商品的數量,咱們也是從redis中拿的,不是頁面上的
  • 咱們能夠把要傳的信息放入一個表單,
  • 表單中的checkbox,只有被選中時,值纔會被提交,
  • 後端增長一個提交訂單的視圖,
  • 1,接收數據,
  • 2,遍歷用戶購買的商品信息,
  • 總的數量,總的價格,
  • 運費,實際開發的時候,是一個子系統,如今咱們把這個寫死,
  • 實際支付,就是總價格+運費,
  • 獲取用戶的地址,只要是這個用戶的,咱們就從數據庫查出來,注意頁面流出來編輯收穫地址的按鈕,
  • 組織上下文,
  • 注意:沒有登錄的時候是不能進入這個頁面的,跳轉到登錄頁面,

建立訂單前端js:mysql

  • 訂單相關的有兩張表,訂單信息表,訂單商品表,
  • 前端的訂單提交頁面,咱們點擊提交訂單,應該提交哪些數據???
  • 商品的id,商品的運費,商品的收穫地址,支付方式,
  • 至於總件數,總金額,這些傳了也不會用,
  • 點擊提交的時候,使用的是ajax請求,

 建立訂單後端的操做git

  • 前端有了js提交以後,咱們後端就能夠去接收這個請求了,
  • 建立訂單的核心業務,
  • 1,用戶下一個訂單,我要往訂單信息表中加入一條信息,這個時候的總數量和總金額,都是0,支付編號不用管,有默認值,訂單狀態一開始都是未支付,
  • 2,往訂單商品表中加入多條記錄,評論剛剛下訂單是沒有的,默認是空,
  • 3,下單成功了以後還須要更新商品的庫存信息,由於以前都是0
  • 4,把購物車中的商品清除,  
  • 5,返回一個應答,下單成功, 

訂單生成-mysql的事物的概念:github

  • 若是一共兩個庫存,可是兩個用戶都加了兩個商品,一個客戶先買了,第二個客戶再次去購買,庫存就是零了,這個時候怎麼辦?
  • 咱們須要在生成訂單的時候判斷庫存,若是大於庫存,咱們應該返回商品庫存不足,
  • 因此整個建立訂單的流程,須要作成一個事務,
  • 什麼是mysql事務,要麼全都執行,要麼所有執行,
  • 特色:
  • 1,原子性,一組事務,要麼成功,要麼撤回
  • 2,穩定性,若是有非法的數據,能夠撤回,
  • 3,事務的隔離性,一個事務的處理結果,若是影響了其餘的事物,其餘的也會撤回
  • 4,可靠性,事務會保存到日誌裏面,軟硬件崩潰了,恢復以後能夠作一個從新執行
  • mysql中事務控制的語句,
  • 1,開啓事務, begin; # 開始事務,後面寫的語句都是在事務裏面,
  • 2,事務的提交 ,commit; # 提交事務
  • 3,事務的回滾,rollback; # 回滾,提交和回滾是事務的兩個操做,
  • 還能夠建立保存點,叫作標記點,
  • 設置保持點的命令:
  • SAVEPOINT savepoint_name; // 聲明一個 savepoint
  • ROLLBACK TO savepoint_name; // 回滾到savepoint,這個點以前的沒有回滾,以後的回滾了,
  • RELEASE SAVEPOINT savepoint_name;  // 刪除指定保留點
  • 一旦開始了一個事務,
  • 要麼是提交了,要麼是回滾,纔是結束,不然都不是結束,
  • 事務中能夠設置保存點,

django中使用事務,ajax

  • 怎麼把django中的是一系列操做放入一個事務裏面呢?
  • 咱們須要一個django的模塊:from django.db import transaction
  • 而後使用    @transaction.atomic,這個裝飾器,裝飾咱們的函數,
  • 把涉及到的數據庫操做放入一個事務裏面,
  • 你只要一裝飾,這個函數就是一個事務,
  • 何時使用保存點呢?
  • 對數據庫的操做分爲兩段,咱們把核心也爲設置一個保存點,
  • # 設置事務保存點,,save_id = transaction.savepoint()
  • # 商品不存在須要回滾,transaction.savepoint_rollback(save_id)
  • # 提交事務,不然不會提交,,transaction.savepoint_commit(save_id)

訂單生成-訂單兵法的問題:redis

  • 舉例:用戶1要買一個雞腿,這個雞腿只有一個了,這是一個進程,
  • 1,要往數據庫中添加一條記錄, 
  • 2,查詢商品雞腿的信息,而後緊接着往訂單商品表加入數據以前,咱們進行一個庫存的判斷,
  • 3,判斷沒有問題,添加記錄,
  • 4,進行商品庫存的更新,
  • 若是在用戶1買的時候,又有一我的去買了這個雞腿,這是第二個進程,
  • 而後也執行這個函數,
  • 這兩個進程是沒有關係的,
  • 多於多進程多線程的時候,調哪個進程是隨機,
  • 假設先調的進程1,判斷庫存的時候假設是能夠的,
  • 如今咱們的電腦切換進程了,切換到了用戶2,這個時候查詢庫存也是夠的,
  • cpu再次進行切換,換進程1,那就更新庫存爲0 了
  • cpu再次進行切換,換進程2,去更新庫存,這個時候你就會發現只有一個雞腿,可是你賣出了兩份,
  • 何時會發生, 就是大量的用戶買一個商品的時候,好比秒殺,好比iPhone,好比小米,這時候就會有訂單併發的問題,

訂單併發的處理:悲觀鎖,sql

  • 賣出的量超過了庫存,這種併發問題怎麼解決,
  • 有兩種解決方法
  • 1,悲觀鎖,
  • 2,樂觀鎖。
  • 首先第一種悲觀鎖,什麼是悲觀鎖,這個就是對應進程中鎖的概念,誰拿到鎖誰就能夠去改,沒有拿到的不能改,
  • 悲觀鎖就是這樣,這個裏面查詢商品的時候我加一個鎖,我拿到這個記錄就把這條記錄鎖定,別的進程就拿不到了,拿不到就要等待,拿到了才能夠處理,
  • 事務提交或者事務回滾的時候,也就是事務結束的時候,就會把這個鎖釋放,
  • 這樣悲觀鎖就解決了這個問題,
  • 怎麼加鎖?
  • 就是查詢的時候,加一個for update,
  • select * from df_goods_sku where id=sku_id for update;
  • 在django中怎麼去寫?
  • sku = GoodsSKU.objects.select_for_update().get(id=sku_id)
  • 在事務中能夠寫保存點:
  • # 設置事務保存點
  • save_id = transaction.savepoint()
  • transaction.savepoint_rollback(save_id)
  • # 提交事務,不然不會提交
  • transaction.savepoint_commit(save_id)

 訂單併發-樂觀鎖:數據庫

  • 在查詢數據的時候不加鎖,在更新時進行判斷,
  • 判斷更新時的庫存和以前的查出的庫存是否一致,
  • 也就是說,我查到的庫存是1,我更新的時候庫存也是1,那就是沒有人對這條數據操做,我就能夠操做這個數據了,
  • # 返回受影響的行數,表示1更新成功,返回0表示更新失敗
  • res = GoodsSKU.objects.filter(id=sku_id, stock=orgin_stock) .update(stock=new_stock, sales=new_sales)
  • 根據這個條件查詢,更新,要麼是1,要麼是0,1就是更新成功了,
  • 更新失敗了,要回滾
  • 更新失敗,說明確實以前被人改了,可是我仍是嘗試3次,再加一個for循環,
  • #######
  • 模擬兩個用戶操做同一個商品,使用悲觀鎖,
  • 1,兩個都提交,都是第一次循環,
  • 2,第一我的提交了以後,查出來仍是庫存沒有變這是怎麼回事
  • 這是由於事務的隔離性,
  • 有四個隔離級別:
  • 1,讀取未提交的內容,
  • 假設有兩個事務,A和B,我在事務A中執行了插入語句,可是我尚未提交,可是這個隔離級別,事務B就能夠查到事務A爲提交的插入語句的內容改變,
  • 這是髒讀,dirty read,這是讀取未提交的內容,
  • 2,讀取提交的內容,
  • 假設有兩個事務,A和B,我在事務A中執行了插入語句,可是我尚未提交,這個時候事務B是拿不到內容的,只有事務A提交了,事務B才能夠查看到,這是大多數數據庫的默認隔離級別,可是不是mysql的
  • 3,可重複讀,
  • 這是mysql的默認的隔離級別,假設有兩個事務,A和B,我在事務A中執行了插入語句,可是我尚未提交,這個隔離級別,即便你提交了,我仍是不拿你提交後的,仍是拿到事務A更新以前的,這就是可重複讀,
  • 這種會出現的問題就是幻讀,在一個事務的兩次查詢中數據筆數不一致,什麼意思?就是數據的列數不一致,
  • 舉例:一個事務查詢了3列數據,而另外一個事務卻在此時插入了幾條新的數據,先前的事務在接下來的查詢中,就會發現有幾列數據是我以前沒有查到的,這就是幻讀,
  • 4,可串行化
  • 這是最高級別的隔離,強制事務進行排序,使事務之間不可能之間相互衝突,從而解決幻讀的問題,可是會致使大量的超時現象和鎖的競爭,處理效率低
  • ############
  • 以前咱們出現的就是由於mysql默認是可重複讀,這種咱們拿不到上一個事務更新以後的庫存,致使我更新是失敗的,因此咱們要更改mysql的事物隔離級別,改成讀取提交的內容,
  • 怎麼設置?
  • 找到mysql的日誌文件,sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
  •  transaction-isolation = READ-COMMITTED
  • 重啓mysql的服務,sudo service mysql restart
  • 這樣就能夠了,

訂單併發-總結:django

  • 在衝突比較少的時候,建議使用樂觀鎖,我沒有加鎖,沒有釋放鎖,就減小了開銷,提交性能,
  • 衝突比較多的時候,使用悲觀鎖
  • 樂觀鎖重複操做的代價比較大,也使用悲觀鎖,

用戶中心-訂單頁面:

  • 提交訂單頁面,點擊提交訂單以後,提交成功,會進入用戶中心的訂單查看頁面,
  • 用戶中心有一個單獨的用戶中心訂單頁面,
  • 後端須要一個視圖,用來返回訂單的信息,
  • 咱們在用戶中心的訂單頁面,看到以前下的可是待支付的狀態,點擊去支付咱們就能夠支付了,
  • 點擊支付會跳轉到支付寶的二維碼頁面,而後登錄就能夠支付了,
  • 須要研究一下支付寶支付的內容,

 

 

訂單支付代碼:

  • 點擊訂單列表頁面,點擊去付款,採用post請求,給django網站傳遞參數,
  • 咱們須要給支付寶傳參數,咱們要使用一個sdk,這樣就不用咱們本身傳參數了,
  • 安裝這個包,https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
  • 先卸載一個包:pip uninstall pycrypto
  • 而後安裝:pip install python-alipay-sdk --upgrade
  • 安裝好了以後,你就有這個包了,你就可使用了,
  • ########
  • 先搞清楚支付寶的沙箱環境,
  • 進入支付寶點開放平臺網站,https://open.alipay.com/
  • 擊「開放平臺-開發者中心-沙箱環境」。進入沙箱環境頁面,系統已經自動爲你建立一個應用,在 信息配置 中能夠看到應用信息。
  • 二.生成密鑰文件
  • 1. 使用OpenSSL
  • openssl
  • 2. 生成私鑰
  • genrsa -out app_private_key.pem 2048
  • 3. 生成公鑰
  • rsa -in app_private_key.pem -pubout -out app_public_key.pem
  • 4. 退出OpenSSL
  • exit
  • ###########
  • 有了本身的公鑰和私鑰了,下一步就是要配置,在支付寶的沙箱環境,設置本身的公鑰,支付寶就會反覆支付寶的公鑰,
  • 這個支付寶的公鑰,是咱們接收到支付寶的內容以後進行解密的,
  • 因此咱們要把這個支付寶的公鑰保存到咱們的項目裏面,
  • 咱們在order應用下面,把支付寶的公鑰,和咱們私鑰都放到這個文件夾下, 
  • 這樣就配置玩了,
  • ##################
  • 怎麼使用?
  • 前端點擊支付的時候使用ajax+post請求,
  • 須要傳遞的參數:order_id,
  • 後端查看這個訂單,有幾個查詢條件,訂單號帶上,是這個用戶的,是支付寶支付方式,是待支付的狀態的,能查到就是一個有效的訂單,
  • 沒有問題下一步就開始調用支付寶的接口了,
  • 1,初始化
  • 2,調接口,
  • 3,返回應答,這裏就是方法pay_url = 'https://openapi.alipaydev.com/gateway.do?' + order_string
  • 報錯:    raise ValueError("RSA key format is not supported")
  • 把接入支付寶的時候的參數改成:app_private_key_string----->  app_private_key_path
  • 報錯:    raise ValueError("Not a valid PEM pre boundary")
  • 原來是個人先後的標記多謝了橫槓,兩邊只能是五個,我寫了7個,-----END RSA PRIVATE KEY-----注意這個標記的兩邊必需要是5個,不是5個就會報這個錯,
  • 如今通了,
  • 如今登陸沙箱環境,查看沙箱帳號,買家帳號密碼

訂單支付-獲取支付結果:

  • 由於咱們如今不是公網環境,因此支付寶不能返回給咱們支付結果,
  • 因此咱們本身去查詢交易的結果,
  • 獲取了支付寶的交易結果以後,給用戶一個支付的結果,支付成功,或者失敗,
  • 用戶瀏覽器訪問咱們的網站,而後看支付是否成功,
  • 用戶的瀏覽器何時訪問咱們的地址,
  • 怎麼設計??
  • 咱們把用戶引導到支付頁面以後,
  • 檢查支付狀態,支付成功了,
  • 彈出支付成功,而後刷新頁面,把數據庫裏面的訂單狀態改掉,

訂單評論:

  • 前端有單獨的評論的頁面,
  • 一個訂單有多個商品,應該有多個評論框,
  • 評論以後提交,訂單的狀態從去評價變爲完成,
  • 在商品詳情頁面就有一個評價,應該要顯示評價, 
相關文章
相關標籤/搜索