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>