最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

django中使用事務及接入支付寶支付功能

 更新時間:2019年09月15日 11:19:29   作者:麥葉  
這篇文章主要介紹了django中使用事務以及接入支付寶支付功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

之前一直想記錄一下在項目中使用到的事務以及支付寶支付功能,自己一直犯懶沒有完,趁今天有點興致,在這記錄一下。

商城項目必備的就是支付訂單的功能,所以就會涉及到訂單的保存以及支付接口的引入。先來看看訂單的保存,在數(shù)據(jù)庫模型涉及之初,將訂單分成了兩個表,一個為訂單表,記錄訂單的基本信息,如訂單號,用戶信息,運費之類,一個為訂單商品表,記錄該訂單中的商品信息。在保存訂單時,肯定會涉及到兩個表的新建和保存,其實還有一張表也需要進行一些修改,那就是商品表,當一個訂單保存成功,意味著本次交易成功,商品售出,商品的庫存應該進行修改。所以,在保存訂單這一操作中,涉及到的表有三張。所以在保存訂單時,多表數(shù)據(jù)的修改,要嘛同時成功,要嘛同時失敗,這就跟數(shù)據(jù)庫中的事務很像,因此,在這里引入事務,來完成訂單保存的功能。

在Django中可以通過 django.db.transaction 模塊提供的 atomic 來定義一個事務, atomic 提供兩種用法,一種是裝飾器,一種是with語句。

from django.db import transaction
@transaction.atomic
def viewfunc(request):
  # 這些代碼會在一個事務中執(zhí)行
  ...
from django.db import transaction
def viewfunc(request):
  # 這部分代碼不在事務中,會被Django自動提交
  ...
  with transaction.atomic():
    # 這部分代碼會在事務中執(zhí)行
    ...  

   

在Django中,還提供了保存點的支持,可以在事務中創(chuàng)建保存點來記錄數(shù)據(jù)的特定狀態(tài),數(shù)據(jù)庫出現(xiàn)錯誤時,可以恢復到數(shù)據(jù)保存點的狀態(tài)

from django.db import transaction
# 創(chuàng)建保存點
save_id = transaction.savepoint() 
# 回滾到保存點
transaction.savepoint_rollback(save_id)
# 提交從保存點到當前狀態(tài)的所有數(shù)據(jù)庫事務操作
transaction.savepoint_commit(save_id)

所以,可以在序列化器的create方法中,創(chuàng)建一個事務,還進行數(shù)據(jù)的修改保存還有新建,若有地方出錯,則直接回滾,若沒有問題則提交事務。代碼如下

   

def create(self, validated_data): """ 保存訂單 """ # 獲取當前下單用戶 user = self.context['request'].user # 組織訂單編號 20170903153611+user.id # timezone.now() -> datetime order_id = timezone.now().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id) address = validated_data['address'] pay_method = validated_data['pay_method'] # 生成訂單 with transaction.atomic(): # 創(chuàng)建一個保存點 save_id = transaction.savepoint() try: # 創(chuàng)建訂單信息 order = OrderInfo.objects.create( order_id=order_id, user=user, address=address, total_count=0, total_amount=Decimal(0), freight=Decimal(10), pay_method=pay_method, status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'] if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH'] else OrderInfo.ORDER_STATUS_ENUM['UNPAID'] ) # 獲取購物車信息 redis_conn = get_redis_connection("cart") redis_cart = redis_conn.hgetall("cart_%s" % user.id) cart_selected = redis_conn.smembers('cart_selected_%s' % user.id) # 將bytes類型轉換為int類型 cart = {} for sku_id in cart_selected: cart[int(sku_id)] = int(redis_cart[sku_id]) # # 一次查詢出所有商品數(shù)據(jù) # skus = SKU.objects.filter(id__in=cart.keys()) # 處理訂單商品 sku_id_list = cart.keys() for sku_id in sku_id_list: while True: sku = SKU.objects.get(id=sku_id) sku_count = cart[sku.id] # 判斷庫存 origin_stock = sku.stock # 原始庫存 origin_sales = sku.sales # 原始銷量 if sku_count > origin_stock: transaction.savepoint_rollback(save_id) raise serializers.ValidationError('商品庫存不足') # 用于演示并發(fā)下單 # import time # time.sleep(5) # 減少庫存 # sku.stock -= sku_count # sku.sales += sku_count # sku.save() new_stock = origin_stock - sku_count new_sales = origin_sales + sku_count # 根據(jù)原始庫存條件更新,返回更新的條目數(shù),樂觀鎖 ret = SKU.objects.filter(id=sku.id, stock=origin_stock).update(stock=new_stock, sales=new_sales) if ret == 0: continue # 累計商品的SPU 銷量信息 sku.goods.sales += sku_count sku.goods.save() # 累計訂單基本信息的數(shù)據(jù) order.total_count += sku_count # 累計總金額 order.total_amount += (sku.price * sku_count) # 累計總額 # 保存訂單商品 OrderGoods.objects.create( order=order, sku=sku, count=sku_count, price=sku.price, ) # 更新成功 break # 更新訂單的金額數(shù)量信息 order.total_amount += order.freight order.save() except serializers.ValidationError: raise except Exception as e: logger.error(e) transaction.savepoint_rollback(save_id) raise # 提交事務 transaction.savepoint_commit(save_id) # 更新redis中保存的購物車數(shù)據(jù) pl = redis_conn.pipeline() pl.hdel('cart_%s' % user.id, *cart_selected) pl.srem('cart_selected_%s' % user.id, *cart_selected) pl.execute() return order

還有一點需要注意的是,當訂單提交,購物車中相應的商品應該進行刪除。好了,以上就是django中的事務。

再來說說支付寶支付功能的引入,現(xiàn)在基本上所有的項目涉及到支付功能時都會引入第三方支付,其中使用最廣泛的應該就是支付寶和微信了,這里我使用的是支付寶支付。當訂單創(chuàng)建完成,接下來就是支付了。

先來縷一下流程,用戶點擊按鈕請求支付寶支付界面,先進行登錄,登錄成功后進行支付操作,支付成功會進行回調。

首先第一步,用戶點擊按鈕,后端會進行url的拼接,將拼接好的url返給前端,前端進行跳轉,跳轉到支付寶相關界面,用戶進行登錄和支付等操作。

查看pythonsdk,首先我們可以通過openssl命令生成一個密鑰(公鑰和私鑰),私鑰自己留存,公鑰用戶校驗。命令如下:

openssl

OpenSSL> genrsa -out app_private_key.pem  2048 # 私鑰 OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 導出公鑰 OpenSSL> exit

同時,你要從支付寶獲得一個公鑰字符串,格式可參考:https://github.com/fzlee/alipay/blob/master/tests/certs/ali/ali_public_key.pem

由于上面我們用的是RSA生成的密鑰,所以在支付寶中我們也需要RSA的公鑰

設置好了密鑰,我們就可以開始寫視圖,代碼如下:

class PaymentView(APIView):
  """
  支付
  """
  permission_classes = (IsAuthenticated,)
  def get(self, request, order_id):
    """
    獲取支付鏈接
    """
    # 判斷訂單信息是否正確
    try:
      order = OrderInfo.objects.get(order_id=order_id, user=request.user,
                     pay_method=OrderInfo.PAY_METHODS_ENUM["ALIPAY"],
                     status=OrderInfo.ORDER_STATUS_ENUM["UNPAID"])
    except OrderInfo.DoesNotExist:
      return Response({'message': '訂單信息有誤'}, status=status.HTTP_400_BAD_REQUEST)
    # 構造支付寶支付鏈接地址
    alipay = AliPay(
      appid=settings.ALIPAY_APPID,
      app_notify_url=None, # 默認回調url
      app_private_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem"),
      alipay_public_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/alipay_public_key.pem"), # 支付寶的公鑰,驗證支付寶回傳消息使用,不是你自己的公鑰,
      sign_type="RSA2", # RSA 或者 RSA2
      debug=settings.ALIPAY_DEBUG # 默認False
    )
    order_string = alipay.api_alipay_trade_page_pay(
      out_trade_no=order_id,
      total_amount=str(order.total_amount),
      subject="美多商城%s" % order_id,
      return_url="http://www.meiduo.site:8080/pay_success.html", 
    )
    # 需要跳轉到https://openapi.alipay.com/gateway.do? + order_string
    # 拼接鏈接返回前端
    alipay_url = settings.ALIPAY_URL + "?" + order_string
    return Response({'alipay_url': alipay_url})

相關的參數(shù)可以提前在配置文件中配置好(ALPAY_APPID,ALPAY_URL,ALPAY_DEBUG)注意ALPAY為True時才啟用沙箱環(huán)境。當用戶支付成功,會對你填寫的回調網址進行回調,返回的參數(shù)如下圖。

 

前端頁面將此數(shù)據(jù)發(fā)送給后端,后端檢驗并保存支付結果。以上就是全部過程。具體的過程可以參考pythonsdk。

總結

以上所述是小編給大家介紹的django中使用事務及接入支付寶支付功能,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!

相關文章

  • Python?hashlib模塊詳情

    Python?hashlib模塊詳情

    本文,我們來對Python?提供的安全哈希算法的通用接口-hashlib模塊進行學習,文章內容具有一定的參考價值,需要的小伙伴可以參考一下
    2021-11-11
  • 使用tensorboard可視化loss和acc的實例

    使用tensorboard可視化loss和acc的實例

    今天小編就為大家分享一篇使用tensorboard可視化loss和acc的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • 利用Python中的輸入和輸出功能進行讀取和寫入的教程

    利用Python中的輸入和輸出功能進行讀取和寫入的教程

    這篇文章主要介紹了利用Python中的輸入和輸出功能進行讀取和寫入的教程,本文來自于IBM官方網站技術文檔,需要的朋友可以參考下
    2015-04-04
  • numpy中的meshgrid函數(shù)的使用

    numpy中的meshgrid函數(shù)的使用

    這篇文章主要介紹了numpy中的meshgrid函數(shù)的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-07-07
  • Tensorflow卷積實現(xiàn)原理+手寫python代碼實現(xiàn)卷積教程

    Tensorflow卷積實現(xiàn)原理+手寫python代碼實現(xiàn)卷積教程

    這篇文章主要介紹了Tensorflow卷積實現(xiàn)原理+手寫python代碼實現(xiàn)卷積教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • python的運算符與表達式你真的了解嗎

    python的運算符與表達式你真的了解嗎

    這篇文章主要為大家介紹了python的運算符與表達式,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • Python利用ROI進行圖像合成的問題小結

    Python利用ROI進行圖像合成的問題小結

    圖像的 ROI (region of interest) 是指圖像中感興趣區(qū)域、在 OpenCV 中圖像設置圖像 ROI 區(qū)域,實現(xiàn)只對 ROI 區(qū)域操作,本文給大家介紹Python利用ROI進行圖像合成的問題小結,感興趣的朋友一起看看吧
    2021-07-07
  • 如何使用python傳入不確定個數(shù)參數(shù)

    如何使用python傳入不確定個數(shù)參數(shù)

    這篇文章主要介紹了如何使用python傳入不確定個數(shù)參數(shù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • 最新評論

    永寿县| 诸暨市| 格尔木市| 罗山县| 五寨县| 肥东县| 卓尼县| 乌拉特中旗| 东乡族自治县| 西青区| 延津县| 平昌县| 资兴市| 辰溪县| 瑞金市| 洛宁县| 闸北区| 伊金霍洛旗| 资中县| 全南县| 盐池县| 大厂| 剑河县| 娄底市| 罗源县| 大同县| 东阿县| 麦盖提县| 墨江| 寿光市| 阳东县| 阜康市| 平塘县| 依安县| 宾阳县| 越西县| 修水县| 盐边县| 青冈县| 瓮安县| 涞源县|