50.Django大型电商项目之订单模块模型类创建与支付宝沙箱支付功能

1.Django中创建模型类

在这里插入图片描述

from django.db import models
from userapp.models import *
# Create your models here.

class Order(models.Model):
    '''订单模块'''
    out_trade_num = models.UUIDField()
    trade_no = models.CharField(max_length=120)
    order_num = models.CharField(max_length=50)
    status = models.CharField(max_length=20, default='待支付')
    payway = models.CharField(max_length=20, default='alipay')
    address = models.ForeignKey(Address, on_delete=models.CASCADE)
    user = models.ForeignKey(UserInfo, on_delete=models.CASCADE)

class OrderItem(models.Model):
    '''订单项'''
    goodsid = models.PositiveIntegerField()
    colorid = models.PositiveIntegerField()
    sizeid = models.PositiveIntegerField()
    count = models.PositiveIntegerField()
    order = models.ForeignKey(Order, on_delete=models.CASCADE)

迁移数据库

python .\manage.py makemigrations
python .\manage.py migrate 

2.支付宝沙箱支付功能

后端

from django.shortcuts import render
from django.shortcuts import render,redirect,HttpResponse
import jsonpickle
from utils.cartmanager import DBCartManger
from utils.alipay_p3 import AliPay
import uuid
from orderapp.models import *
from datetime import datetime
from userapp.models import *
from goodsapp.models import *
from django.db.models import F
# Create your views here.
# 跳转结算视图
def toOrder(request):
    # 获取购物车页面传递的参数
    cartitems = request.GET.get('cartitems','')
    totalPrice = request.GET.get('totalPrice',0)
    # 判断用户是否登录
    # 从session对象中获取用户信息
    if not request.session.get('user',''):
        # 如果没有登录,跳转登录页面,进行登录
        return render(request, 'userapp/login.html',{'reflag':'orderapp', 'cartitems':cartitems, 'totalPrice':totalPrice})
    # 获取登录用户默认地址信息
    user = jsonpickle.loads(request.session.get('user'))
    # 根据user对象获取默认地址
    addrObj = user.address_set.get(isdefault=True)

    # 获取订单中的商品信息
    cartitemsList = jsonpickle.loads(cartitems)
    # cartitemList ["{\"goodsid\":\"4\",\"sizeid\":\"9\",\"colorid\":\"9\"}","{\"goodsid\":\"4\",\"sizeid\":\"6\",\"colorid\":\"10\"}"]
    # 循环遍历cartitemList生成CartItem对象的列表
    # 创建DBCartManager实例对象——调用工具类的获取数据方法
    dbCartObj = DBCartManger(user)
    print(cartitemsList,'-----------------------------------+++++')
    cartitemObjList = [dbCartObj.get_cartitems(**eval(item)) for item in cartitemsList]
    return render(request, 'orderApp/toOrder.html',{'addrObj':addrObj, 'cartitemObjList':cartitemObjList,'totalPrice':totalPrice})



# 创建AliPay实例对象
alipay = AliPay(appid = '2021000121697847',
    app_notify_url = 'http://127.0.0.1:8000/orderapp/checkPay/', 
    app_private_key_path='keys/my_private_key.txt',
    alipay_public_key_path='keys/alipay_public_key.txt',
    return_url = 'http://127.0.0.1:8000/orderapp/checkPay/', 
    debug=True)

def toPay(request):
    # 获取支付金额
    totalPrice = request.GET.get('totalPrice',0)
    # 获取请求参数

    # 保存订单
    orderObj = Order.objects.create(out_trade_num=uuid.uuid4().hex,
                                    order_num = datetime.strftime(datetime.now(),'%Y%m%d%H%M%S'),
                                    payway=request.GET.get('payway',''),
                                    address = Address.objects.get(id=request.GET.get('address','')),
                                    user = jsonpickle.loads(request.session.get('user')))
    # 保存订单项
    cartitems = jsonpickle.loads(request.GET.get('cartitems',''))
    orderItemList = [OrderItem.objects.create(order=orderObj,**ci) for ci in cartitems if ci]

    # 调用支付界面
    params = alipay.direct_pay(subject='淘宝商城', out_trade_no=orderObj.out_trade_num, total_amount=totalPrice)
    return redirect(alipay.gateway+"?"+params)

def checkPay(request):
    # 获取所有的请求参数
    params = request.GET.dict()
    # 获取sign的值
    sign = params.pop('sign')
    # 判断是否支付成功
    if alipay.verify(params, sign):
        # 1. 修改订单状态,以及trade_no设置值
        # 获取订单
        orderObj = Order.objects.get(out_trade_num=params.get('out_trade_no',''))
        orderObj.status = '待发货'
        orderObj.trade_no = params.get('trade_no')

        # 2.修改库存
        # 根据订单获取订单项
        orderitems = orderObj.orderitem_set.all()
        [Inventory.objects.filter(goods_id=oi.goodsid, color_id=oi.colorid, size_id=oi.sizeid).update(count=F('count')-oi.count) for oi in orderitems]

        # 3.更新购物车表中的数据
        # 获取当前用户
        user = jsonpickle.loads(request.session.get('user'))
        [user.cartitem_set.filter(goodsid=oi.goodsid, colorid=oi.colorid, sizeid=oi.sizeid, count=oi.count).delete() for oi in orderitems]


        return HttpResponse('支付成功')
    else:
        return HttpResponse('支付失败')

前端

{% extends 'base.html' %}
{% block title %}结算页面{% endblock %}

{% load static %}

{% block headercss %}
    <link rel="stylesheet" type="text/css" href="{% static 'css/public.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/proList.css' %}">
{% endblock %}

{% block main %}
<div class="order cart mt">
    <!-----------------site------------------->
    <div class="site">
        <p class="wrapper clearfix">
            <span class="fl">订单确认</span>
        </p>
    </div>
    <!-----------------orderCon------------------->
    <div class="orderCon wrapper clearfix">
        <div class="orderL fl">
            <!--------h3---------------->
            <h3>收件信息</h3>
            <!--------addres---------------->
            <div class="addres clearfix">
                <div class="addre fl on">
                    <div class="tit clearfix">
                        <p class="fl"><span id="name_address">{{addrObj.aname}}</span>
                            <span class="default">[默认地址]</span>
                        </p>
                    </div>
                    <div class="addCon">
                        <p id="address_address">{{addrObj.addr}}</p>
                        <p id="phone_address">{{addrObj.phone}}</p>
                    </div>
                </div>
            </div>
            <h3>支付方式</h3>
            <!--------way---------------->
            <div class="way clearfix">
                <img class="on" src="{% static 'images/way01.jpg' %}" name="alipay">
                <img src="{% static 'images/way02.jpg' %}" name="wechat">
                <img src="{% static 'images/way03.jpg' %}" name="union">

            </div>

            <!--------dis---------------->

        </div>
        <div class="orderR fr">
            <div class="msg">
                <h3>订单内容</h3>
                <!--------ul---------------->


    {% for cartitem in cartitemObjList %}              
        <ul class="clearfix" goodsid="{{cartitem.goodsid}}" sizeid="{{cartitem.sizeid}}" colorid="{{cartitem.colorid}}" count="{{cartitem.count}}">
            <li class="fl">
                <img src="{{ cartitem.getColor.colorurl }}" width="87px" height="87px">
            </li>
            <li class="fl">
                <p>{{cartitem.getGoods.gname}}</p>
                <p>{{cartitem.getColor.colorname}}</p>
                <p>数量:{{cartitem.count}}</p>
            </li>
            <li class="fr">¥{{totalPrice}}</li>
        </ul>
    {% endfor %}

            </div>
            <!--------tips---------------->
            <div class="tips">
                <p><span class="fl">商品金额:</span><span class="fr">¥{{totalPrice}}</span></p>
                <p><span class="fl">优惠金额:</span><span class="fr">¥0.00</span></p>
                <p><span class="fl">运费:</span><span class="fr">免运费</span></p>
            </div>
            <!--------tips count---------------->
            <div class="count tips">
                <p><span class="fl">合计:</span><span class="fr">¥{{totalPrice}}</span></p>
            </div>
            <!--<input type="button" name="" value="去支付"> -->
            <a href="http://127.0.0.1:8000/order/order.html" id="pay" class="pay" onclick="javascript:void(0);">去支付</a>
        </div>
    </div>
</div>
{% endblock %}


{% block footerjs %}
<script src="{% static 'js/public.js' %}" type="text/javascript" charset="utf-8"></script>
<script src="{% static 'js/pro.js' %}" type="text/javascript" charset="utf-8"></script>
<script src="{% static 'js/user.js' %}" type="text/javascript" charset="utf-8"></script>

<script>
    $("#pay").click(function(){
        var cartitems = []

        $.each($('.msg ul'),function(index,item){
            cartitems.push({"goodsid":$(item).attr('goodsid'),
                            "sizeid":$(item).attr('sizeid'),
                            "colorid":$(item).attr('colorid'),
                            "count":$(item).attr('count')
                            })

        })


        //拼接请求参数
        var params = 'address={{addrObj.id}}&payway='+$('.way .on').attr('name')+'&cartitems='+JSON.stringify(cartitems)+"&totalPrice={{totalPrice}}"

        //拼接请求地址
        var url = '/orderapp/toPay/?'+params

        $(this).attr('href',url)

    })

</script>
{% endblock %}

效果展示

若想了解具体支付功能可以查看本专栏上一节的demo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想成为数据分析师的开发工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值