【Django】网上蛋糕项目商城-购物车和我的订单功能

1.购物车功能

在首页中的滚动栏的商品,热门商品,新品,以及商品详情中都有加入购物车按钮

在models文件中创建购物车表,用于保存当前用户添加的商品信息

# 购物车表
class ShoppingCar(models.Model):
    # 用户id
    userId=models.IntegerField()
    # 商品id
    goodsId=models.IntegerField()
    # 商品数量
    goodsNumber=models.IntegerField()

并执行python manage.py makemigrations生成迁移数据库文件

再执行python manage.py migrate生成数据库表

点击加入购物车后,向服务器发出请求,不同页面发出的请求,携带的参数信息不同

在urls文件中定义接收该请求的地址

path('goods_buy/',views.goods_buy),

在views文件中定义处理该请求的函数

# 处理添加购物车功能
def goods_buy(request):
    # 创建购物车表,判断用户是否登录,如果登录,将用户选中的商品id添加至购物车表,未登录,则跳转至登录页面
    # 先判断是否登录
    isLogin=request.session.get("isLogin")
    if not isLogin:
        return redirect(login)
    # 然后判断库存是否充足
    # 获取url地址
    url = request.GET["url"]
    # 获得将要购买的商品的id
    goodsid = request.GET["id"]
    # 根据商品id查询该商品
    g = Goods.objects.get(id=goodsid)
    # 判断该商品是否还有库存
    if g.stock <= 0:
        key="failMsg"
        value="库存不足,请购买其他商品!"
        request.session[key]=value
        if "index" == url:
            return redirect(index)
        elif "recommend"==url:
            t=request.GET["type"]
            return HttpResponseRedirect("/goodsrecommend_list/?type=" + t)
        elif "search"==url:
            keyword=request.session.get("keyword")
            return HttpResponseRedirect("/goods_search/?keyword=" + keyword)
        elif "list"==url:
            typeId=request.session.get("typeId")
            return HttpResponseRedirect("/goods_list/?typeid=" + typeId)
        else:
            return HttpResponseRedirect("/goods_detail/?id="+goodsid)
    else:
        key="msg"
        value="已添加到购物车!"
        request.session[key] = value
        # 再判断该用户的购物车是否已添加过该商品,如果有,则修改该商品购物车中的数量
        u=request.session.get("user")
        sc=ShoppingCar.objects.filter(userId=u["id"],goodsId=goodsid)
        if sc:
            number=sc[0].goodsNumber
            number=number+1
            sc.update(goodsNumber=number)
        # 如果没有,则添加该商品信息到购物车中
        else:
            ShoppingCar.objects.create(userId=u["id"],goodsId=goodsid,goodsNumber=1)

        # 查询出,当前用户的购物车总数
        shops=ShoppingCar.objects.filter(userId=u["id"]).values()
        total=0
        for shop in shops:
            total+=shop["goodsNumber"]
        request.session["total"]=total
        # 最后根据url的参数值判断刷新哪个页面
        if "index" == url:
            return redirect(index)
        elif "recommend"==url:
            t=request.GET["type"]
            return HttpResponseRedirect("/goodsrecommend_list/?type=" + t)
        elif "search" == url:
            keyword = request.session.get("keyword")
            return HttpResponseRedirect("/goods_search/?keyword=" + keyword)
        elif "list"==url:
            typeId=request.session.get("typeId")
            return HttpResponseRedirect("/goods_list/?typeid=" + typeId)
        else:
            return HttpResponseRedirect("/goods_detail/?id=" + goodsid)

并同时刷新header.html头部页面中的购物车总数,因此需要在首页的函数中添加以下代码

 u = request.session.get("user")
    if u:
        # 查询出,当前用户的购物车总数
        shops = ShoppingCar.objects.filter(userId=u["id"]).values()
        total = 0
        for shop in shops:
            total += shop["goodsNumber"]
        request.session["total"] = total

在登录成功之后,获取该用户的购物车数据,在登录的函数中添加以下代码

# 查询出,当前用户的购物车总数
        shops = ShoppingCar.objects.filter(userId=u["id"]).values()
        total = 0
        for shop in shops:
            total += shop["goodsNumber"]
        request.session["total"] = total

点击上图中的购物车,进入购物车页面

 在urls文件中定义接收该请求

path('goods_cart/',views.goods_cart),

在views文件中创建该函数处理该请求

# 获取购物车数据,跳转至购物车页面
def goods_cart(request):
    # 先判断是否登录
    isLogin = request.session.get("isLogin")
    if not isLogin:
        return redirect(login)
    # 根据当前登录的用户,查询出该用户添加在购物车中的所有商品
    u=request.session.get("user")
    sc=ShoppingCar.objects.filter(userId=u["id"]).values()
    # 遍历每一个商品,根据商品编号查询商品详细信息的数据
    totalPrice=0.0
    for s in sc:
        goods=Goods.objects.filter(id=s["goodsId"]).values()
        s["goods"]=goods[0]
        # 计算每一个商品的总金额
        n1=float(s["goodsNumber"])
        n2=float(goods[0]["price"])
        totalPrice = totalPrice+(n1*n2)

    return render(request,"goods_cart.html",{"typeList": types,"sc":sc,"totalPrice":totalPrice})
<!DOCTYPE html>
<html>
<head>
	<title>购物车</title>
    {% load static %}
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<link type="text/css" rel="stylesheet" href="{% static 'css/bootstrap.css' %}">
	<link type="text/css" rel="stylesheet" href="{% static 'css/style.css' %}">
	<script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
	<script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
	<script type="text/javascript" src="{% static 'layer/layer.js' %}"></script>
	<script type="text/javascript" src="{% static 'js/cart.js' %}"></script>
</head>
<body>
	{% include "header.html" with flag=7 typeList=typeList %}
	<div class="cart-items">
		<div class="container">
			<h2>我的购物车</h2>
            {% for s in sc %}
            <div class="cart-header col-md-6">
					<div class="cart-sec simpleCart_shelfItem">
						<div class="cart-item cyc">
							<a href="/goods_detail/?id={{ s.goodsId }}">
								<img src="{% static s.goods.cover %}" class="img-responsive">
							</a>
						</div>
						<div class="cart-item-info">
							<h3><a href="/goods_detail/?id={{ s.goodsId }}">{{ s.goods.name }}</a></h3>
							<h3><span>单价: ¥ {{ s.goods.price }}</span></h3>
							<h3><span>数量: {{ s.goodsNumber }}</span></h3>
							<a class="btn btn-info" href="/addShops/?id={{ s.goodsId }}">增加</a>
							<a class="btn btn-warning" href="/removeShops/?id={{ s.goodsId }}">减少</a>
							<a class="btn btn-danger" href="/deleteShops/?id={{ s.goodsId }}">删除</a>
						</div>
						<div class="clearfix"></div>
					</div>
				</div>
            {% endfor %}
			
			<div class="cart-header col-md-12">
				<hr>
				<h3>订单总金额: ¥ {{ totalPrice }}</h3>
				<a class="btn btn-success btn-lg" style="margin-left:74%" href="/order_submit/?totalPrice={{ totalPrice }}">提交订单</a>
			</div>
		</div>
	</div>
	{% include "footer.html" %}

</body>
</html>

点击增加按钮,向服务器发送请求,修改购物车表,给指定的商品增加商品数量

在urls文件中定义接收该请求的地址

path('addShops/',views.addShops),

在views文件中定义处理该请求的函数

# 购物车中增加商品
def addShops(request):
    # 先判断是否登录
    isLogin = request.session.get("isLogin")
    if not isLogin:
        return redirect(login)
    # 获取商品id
    goodsId=request.GET["id"]
    u = request.session.get("user")
    sc=ShoppingCar.objects.filter(goodsId=goodsId,userId=u["id"])
    sc.update(goodsNumber=(sc[0].goodsNumber+1))
    # 查询出,当前用户的购物车总数
    shops = ShoppingCar.objects.filter(userId=u["id"]).values()
    total = 0
    for shop in shops:
        total += shop["goodsNumber"]
    request.session["total"] = total
    return redirect(goods_cart)

这样当在购物车列表页面中,选中其中某个商品点击添加按钮,则会修改购物车表中该商品的数量,并同步统计购物车的商品总价格。

点击减少按钮,向服务器发送请求,修改购物车表,给指定的商品减少商品数量

在urls文件中定义该请求地址

path('removeShops/',views.removeShops),

在views文件中创建函数处理该请求

# 购物车中删除减少商品
def removeShops(request):
    # 先判断是否登录
    isLogin = request.session.get("isLogin")
    if not isLogin:
        return redirect(login)
    # 获取商品id
    goodsId = request.GET["id"]
    u = request.session.get("user")
    sc = ShoppingCar.objects.filter(goodsId=goodsId, userId=u["id"])
    if sc[0].goodsNumber == 1:
        # 如果当前商品数量为1,再减少则表示删除该商品
        sc.delete()
    else:
        sc.update(goodsNumber=(sc[0].goodsNumber - 1))
    # 查询出,当前用户的购物车总数
    shops = ShoppingCar.objects.filter(userId=u["id"]).values()
    total = 0
    for shop in shops:
        total += shop["goodsNumber"]
    request.session["total"] = total
    return redirect(goods_cart)

点击删除按钮,向服务器发送请求,修改购物车表,给指定的商品删除该商品

 在urls文件中定义该请求地址

path('deleteShops/',views.deleteShops),

在views文件中创建处理该请求的函数

# 购物车中删除商品
def deleteShops(request):
    # 先判断是否登录
    isLogin = request.session.get("isLogin")
    if not isLogin:
        return redirect(login)
    # 获取商品id
    goodsId = request.GET["id"]
    u = request.session.get("user")
    sc = ShoppingCar.objects.filter(goodsId=goodsId, userId=u["id"])
    sc.delete()
    # 查询出,当前用户的购物车总数
    shops = ShoppingCar.objects.filter(userId=u["id"]).values()
    total = 0
    for shop in shops:
        total += shop["goodsNumber"]
    request.session["total"] = total
    return redirect(goods_cart)

2.提交订单

点击购物车页面中的提交订单按钮

在urls文件中定义该请求的地址

path('order_submit/',views.order_submit),

在views文件中处理该请求

# 提交订单请求
def order_submit(request):
    # 先判断是否登录
    isLogin = request.session.get("isLogin")
    if not isLogin:
        return redirect(login)
    totalPrice=request.GET["totalPrice"]
    request.session["totalPrice"]=totalPrice
    return render(request,"order_submit.html",{"typeList": types})
<!DOCTYPE html>
<html>
<head>
	<title>支付</title>
    {% load static %}
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<link type="text/css" rel="stylesheet" href="{% static 'css/bootstrap.css' %}">
	<link type="text/css" rel="stylesheet" href="{%  static 'css/style.css' %}">
	<script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
	<script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
	<script type="text/javascript" src="{% static 'layer/layer.js' %}"></script>
	<script type="text/javascript" src="{% static 'js/cart.js' %}"></script>
</head>
<body>
	{% include "header.html" with  typeList=typeList %}
	<div class="cart-items">
		<div class="container">
			<h2>确认收货信息</h2>
			<form class="form-horizontal" action="/order_confirm/" method="post" id="payform">
                {% csrf_token %}
				<div class="row">
					<label class="control-label col-md-1">收货人</label>
					<div class="col-md-6">
						<input type="text" class="form-control" name="name" value="{{ request.session.user.name  }}" style="height:auto;padding:10px;" placeholder="输入收货人" required="required"><br>
					</div>
				</div>
				<div class="row">
					<label class="control-label col-md-1">收货电话</label>
					<div class="col-md-6">
						<input type="text" class="form-control" name="phone" value="{{ request.session.user.phone  }}" style="height:auto;padding:10px;" placeholder="输入收货电话" required="required"><br>
					</div>
				</div>
				<div class="row">
					<label class="control-label col-md-1">收货地址</label>
					<div class="col-md-6">
						<input type="text" class="form-control" name="address" value="{{ request.session.user.address  }}" style="height:auto;padding:10px;" placeholder="输入收货地址" required="required"><br>
					</div>
				</div>
				<br><hr><br>
				<h2>选择支付方式</h2>
				<h3>支付金额:  ${{ request.session.totalPrice }}</h3><br><br>
				<div class="col-sm-6 col-md-4 col-lg-3 " >
					<label>
						<div class="thumbnail">
							<input type="radio" name="paytype" value="1" checked="checked" />
							<img src="{% static 'images/wechat.jpg' %}" alt="微信支付">
						</div>
					</label>
				</div>
				<div class="col-sm-6 col-md-4 col-lg-3 " >
					<label>
						<div class="thumbnail">
							<input type="radio" name="paytype" value="2"  />
							<img src="{% static 'images/alipay.jpg' %}" alt="支付宝支付">
						</div>
					</label>
				</div>
				<div class="clearfix"> </div>
				<div class="register-but text-center">
					<input type="submit" value="确认订单">
					<div class="clearfix"> </div>
				</div>
			</form>
		</div>
	</div>
	<!--footer-->
	{% include "footer.html" %}
	<!--//footer-->
	<script type="text/javascript">
		function dopay(paytype){
			$("#paytype").val(paytype);
			$("#payform").submit();
		}
	</script>

</body>
</html>

点击确认订单按钮,将订单详情信息添加至数据库中

在urls文件中定义请求地址

path('order_confirm/',views.order_confirm),

在views文件中定义处理该请求的函数

# 处理添加订单请求
def order_confirm(request):
    # 收件人
    name=request.POST["name"]
    # 手机号
    phone=request.POST["phone"]
    # 收货地址
    address=request.POST["address"]
#   支付方式
    paytype=request.POST["paytype"]
#    支付状态为2,已付款
    status=2
    # 获取当前的时间
    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    # 总金额
    totalPrice=request.session.get("totalPrice")
    # 总数量
    totalnum=request.session.get("total")
    #用户id
    u=request.session.get("user")
    order=Order.objects.create(name=name,phone=phone,address=address,
                         paytype=paytype,status=status,total=totalPrice,
                         amount=totalnum,datetime=current_time,user_id=u["id"])
    # 获得订单编号
    orderId=order.id
    # 将该订单中包含的所有商品信息添加至子订单中
    # 查询该用户的所有购物车商品编号
    sc=ShoppingCar.objects.filter(userId=u["id"])
    for s in sc:
        goodsId=s.goodsId # 商品编号
        number=s.goodsNumber # 商品数量
        goods=Goods.objects.get(id=goodsId)
        tPrice= goods.price * number # 该商品的总价
        # 将以上信息添加至子订单中
        			      OrderItem.objects.create(price=tPrice,amount=number,goods_id=goodsId,order_id=orderId)

    # 将购物车中该用户的商品清空
    sc.delete()
    request.session["total"] = 0

    return render(request,"order_success.html",{"msg":"订单支付成功!","typeList": types})
<!DOCTYPE html>
<html>
<head>
	<title>支付成功</title>
    {% load static %}
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<link type="text/css" rel="stylesheet" href="{% static 'css/bootstrap.css' %}">
	<link type="text/css" rel="stylesheet" href="{% static 'css/style.css' %}">
	<script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
	<script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
	<script type="text/javascript" src="{% static 'layer/layer.js' %}"></script>
	<script type="text/javascript" src="{% static 'js/cart.js' %}"></script>
</head>
<body>
	{% include "header.html" with  typeList=typeList %}

	<div class="cart-items">
		<div class="container">
            {% if msg %}
            <div class="alert alert-success">{{ msg  }}</div>
            {% endif %}


			<p><a class="btn btn-success" href="/order_list">查看我的订单</a></p>
		</div>
	</div>
	{% include "footer.html" %}
</body>
</html>

3.我的订单功能

点击上图中的查看我的订单,或者是头部导航栏中的我的订单触发请求

在urls文件中定义该请求地址

path('order_list/',views.order_list),

在views文件中创建函数处理该请求

# 处理订单列表的请求
def order_list(request):
    # 先判断是否登录
    isLogin = request.session.get("isLogin")
    if not isLogin:
        return redirect(login)
    u=request.session.get("user")
    # 根据用户id查询订单列表
    orders=Order.objects.filter(user_id=u["id"]).values()
    # 根据订单编号查所有子订单
    for order in orders:
        order["datetime"]=str(order["datetime"])
        items = OrderItem.objects.filter(order_id=order["id"]).values()
        # 根据每个子订单中的商品编号查询商品名称
        for item in items:
            goods=Goods.objects.filter(id=item["goods_id"]).values()
            item["goods"]=goods[0]
        order["items"]=items

    return render(request,"order_list.html",{"typeList": types,"orders":orders})
<!DOCTYPE html>
<html>
<head>
    <title>我的订单</title>
    {% load static %}
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link type="text/css" rel="stylesheet" href="{% static 'css/bootstrap.css' %}">
    <link type="text/css" rel="stylesheet" href="{% static 'css/style.css' %}">
    <script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'layer/layer.js' %}"></script>
    <script type="text/javascript" src="{% static 'js/cart.js' %}"></script>
</head>
<body>
{% include "header.html" with flag=5 typeList=typeList %}
<div class="cart-items">
    <div class="container">
        <h2>我的订单</h2>
        <table class="table table-bordered table-hover">
            <tr>
                <th width="10%">ID</th>
                <th width="10%">总价</th>
                <th width="20%">商品详情</th>
                <th width="20%">收货信息</th>
                <th width="10%">订单状态</th>
                <th width="10%">支付方式</th>
                <th width="20%">下单时间</th>
            </tr>
            {% for order in orders %}
                <tr>
                    <td><p>{{ order.id }}</p></td>
                    <td><p>{{ order.total }}</p></td>
                    <td>
                        {% for item in order.items %}
                            <p>{{ item.goods.name }}(${{ item.goods.price }}) x {{ item.amount }}</p>
                        {% endfor %}
                    </td>
                    <td>
                        <p>{{ order.name }}</p>
                        <p>{{ order.phone }}</p>
                        <p>{{ order.address }}</p>
                    </td>
                    <td>
                        <p>
                            {% if order.status == 2 %}
                                <span style="color:red;">已付款</span>
                            {% endif %}
                            {% if order.status == 3 %}
                                <span style="color:green;">已发货</span>
                            {% endif %}
                            {% if order.status == 4 %}
                                <span style="color:black;">已完成</span>
                            {% endif %}
                        </p>
                    </td>
                    <td>
                        <p>
                            {% if order.paytype == 1 %}
                                微信
                            {% endif %}
                            {% if order.paytype == 2 %}
                                支付宝
                            {% endif %}
                            {% if order.paytype == 3 %}
                                货到付款
                            {% endif %}
                        </p>
                    </td>
                    <td><p>{{ order.datetime }}</p></td>
                </tr>
            {% endfor %}
        </table>
    </div>
</div>
{% include "footer.html" %}
</body>
</html>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

笔触狂放

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

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

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

打赏作者

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

抵扣说明:

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

余额充值