Django 專案總結(12)- 訂單部分
訂單部分
基本功能:提交訂單、儲存訂單
建立訂單資料表,分為兩個表,一個訂單基本資訊表,一個訂單商品表
訂單結算
get 請求
- 使用者點選去結算,跳轉到提交訂單頁面
- 同時向後端傳送請求
- 後端從 redis 資料庫中查詢出已勾選的 sku_id,查詢出對應的商品資訊
- 還需要新增上運費,在這裡運費是寫死的,沒有進行計算,這個都好說,運費欄位要使用 python 自帶的 decimal 庫中的 Decamal 類,這樣數字才不會被進行約等於,而是輸入多少就是多少
- 將資料進行序列化然後返回
- 最後在前端進行展示,並計算好金錢,前端在請求時還會在請求一下地址來讓使用者進行勾選,可以選擇支付方式
儲存訂單
post 請求 引數是 地址 和 支付方式, 後端生成訂單編號,儲存並返回
這裡是需要進行建立,檢視繼承自 CreateAPIView 類,在序列化器中重寫 create 方法進行建立即可
-
create 流程
-
獲取當前下單使用者,context[‘request’].user,在序列化器中,context 中會包含 request 物件,從中獲取就行
-
生成訂單編號,使用當前時間加上使用者 id 的方式來生成
-
在序列化器中校驗過的資料就可以使用 validated_data 來取得地址和支付方式
-
生成訂單,考慮到要同時操作三張表 OrderInfo 表、SKU 表、OrderGoods,所以就需要開啟事務
-
使用
with transaction.atomic():
開啟一個事務 -
建立一個儲存點,方便出現錯誤時進行回退,
save_id = transaction.savepoint()
-
建立訂單資訊,將對應的欄位填充進去
-
從 redis 中查詢出要結算的購物車資料,取出所有要結算的商品 id
-
遍歷商品 id,在這裡考慮到了商品併發下單問題,這裡使用樂觀鎖來解決,就是在迴圈中,每次都進行查詢,在更新的時候再次進行查詢,判斷一下商品數量是否和第一次查詢的一樣,不一樣就跳過,只有一樣才能更新成功,就像電商常用的秒殺一樣,看著在下單介面,但是一直轉圈,轉了半天來了一句庫存不足,大概就是這個原因吧
-
查詢出當前的商品物件,取出要結算的當前商品的數量,儲存一下當前庫存
-
判斷一下庫存,如果不足直接退回到儲存點
transaction.savepoint_rollback(save_id)
,並丟擲錯誤 -
庫存充足,需要進行庫存和銷量的更新,更新時需要再次進行查詢,條件是最開始查詢出的庫存等於當前庫存,這樣才能更新成功
SKU.object.filter(id=sku.id, stock=origin_stock).update(stock=new_stock, sales=origin_sales)
-
更新商品銷量的資訊
-
更新訂單的總數和總金額
-
儲存訂單商品,插入對應的資料,執行完結束當前迴圈
-
給金額加上運費
-
新增上異常捕獲,一個是
serializers.ValidationError
,這個異常自己進行了回滾;還有就是其他異常的捕獲,就需要自己進行異常的捕獲 -
當所有的執行完畢,將事務進行提交,這樣資料庫更新才完成
-
最後從 redis 中刪除已結算的商品資料
-
訂單儲存完畢跳轉到下單成功頁面,根據使用者選擇的付款方式進行展示