13. 项目实战前台之下单操作
优质
小牛编辑
130浏览
2023-12-01
- 本节将实现商城项目中会员下单操作模块:填写收货地址、确认订单信息和执行下单等操作。
(1). 开发前的准备工作:
在数据库 shopdb 中已存在订单表orders和订单详情表detail。
在执行下单操作前要确认会员必须在登录后状态(使用中间件验证)。
#在myobject/common/shopmiddleware.py中的__call__()方法中条件如下代码
# ... ...
# 网站前台登录用户判断(订单操作和会员中心操作需登录)
if re.match("^/orders",path) or re.match("^/vip",path):
# 判断当前用户是否没有登录
if "vipuser" not in request.session:
# 执行登录界面跳转
return redirect(reverse('login'))
response = self.get_response(request)
# Code to be executed for each request/response after
# the view is called.
return response
- 在common应用目录中的myobject/common/models.py 模型文件中,已存在Orders和Detail模型类的定义。
# ... ...
# 订单模型
class Orders(models.Model):
uid = models.IntegerField()
linkman = models.CharField(max_length=32)
address = models.CharField(max_length=255)
code = models.CharField(max_length=6)
phone = models.CharField(max_length=16)
addtime = models.DateTimeField(default=datetime.now)
total = models.FloatField()
state = models.IntegerField()
class Meta:
db_table = "orders" # 更改表名
#订单详情模型
class Detail(models.Model):
orderid = models.IntegerField()
goodsid = models.IntegerField()
name = models.CharField(max_length=32)
price = models.FloatField()
num = models.IntegerField()
class Meta:
db_table = "detail" # 更改表名
在商品购物车页中处理下单按钮,完成向下单操作界面的传值和跳转:
首先将实现准备的
topNav.js
替换掉项目中的web/js/topNav.js
<div onclick="window.location='/orders/add?ids='+loadTotal().join(',')" class="mz-btn btn-success" id="cartSubmit">去结算</div>
(2). 项目urls路由信息配置
- 打开根路由文件:myobject/web/urls.py路由文件,编辑路由配置信息:
from django.conf.urls import url
from web.views import index,cart,orders
urlpatterns = [
#网站前台
# ... ...
# 会员及个人中心等路由配置
# ... ...
# 购物车路由
# ... ...
# 订单处理
url(r'^orders/add$', orders.add,name='orders_add'), #订单的表单页
url(r'^orders/confirm$', orders.confirm,name='orders_confirm'), #订单确认页
url(r'^orders/insert$', orders.insert,name='orders_insert'), #执行订单添加操作
]
(3). 编辑视图文件
- 新建视图文件:myobject/web/views/orders.py 视图文件,并进行编辑
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import redirect
from django.core.urlresolvers import reverse
from common.models import Goods,Types,Orders,Detail
from datetime import datetime
# 公共信息加载
def loadinfo(request):
'''公共信息加载'''
context = {}
lists = Types.objects.filter(pid=0)
context['typelist'] = lists
return context
def add(request):
'''下订单第一步:订单表单'''
context = loadinfo(request)
# 获取要结算商品的id号
ids = request.GET.get("ids",'')
if len(ids) == 0:
context = {"info":"请选择要结算的商品!"}
return render(request,"web/ordersinfo.html",context)
gidlist = ids.split(',')
# 从购物车获取要结算所有商品,并放入到orderslist中,并且累计总金额
shoplist = request.session['shoplist']
orderslist = {}
total = 0.0
for gid in gidlist:
orderslist[gid] = shoplist[gid]
total += shoplist[gid]['price']*shoplist[gid]['m']
# 将这些信息放入到session中
request.session['orderslist'] = orderslist
request.session['total'] = total
return render(request,"web/ordersadd.html",context)
def confirm(request):
context = loadinfo(request)
return render(request,"web/ordersconfirm.html",context)
def insert(request):
context = loadinfo(request)
try:
# 执行订单信息添加操作
od = Orders()
od.uid = request.session['vipuser']['id'] #当前登录者的id号
od.linkman = request.POST.get('linkman')
od.address = request.POST.get('address')
od.code = request.POST.get('code')
od.phone = request.POST.get('phone')
od.addtime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
od.total = request.session['total']
od.state = 0
od.save()
# 执行订单详情添加
orderslist = request.session['orderslist']
shoplist = request.session['shoplist']
for shop in orderslist.values():
del shoplist[str(shop['id'])]
ov = Detail()
ov.orderid = od.id
ov.goodsid = shop['id']
ov.name = shop['goods']
ov.price = shop['price']
ov.num = shop['m']
ov.save()
del request.session['orderslist']
del request.session['total']
request.session['shoplist'] = shoplist
context = {"info":"订单添加成功!订单号:"+str(od.id)}
return render(request,"web/ordersinfo.html",context)
except Exception as err:
print(err)
context = {"info":"订单添加失败,请稍后再试!"}
return render(request,"web/ordersinfo.html",context)
(4). 编写模板文件
- 4.1. 打开购物车模板:/templates/web/cart.html ,编辑js代码,替换topNav.js文件
{% extends "web/base.html" %}
{% load static from staticfiles %}
{% block mylink %}
<link rel="stylesheet" type="text/css" href="{% static 'web/css/cart.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'web/css/cart-app.css' %}">
{% endblock %}
{% block mainbody %}
<div class="mainbody cart" style="margin-top: 80px;">
<div class="container">
<!-- 购物车详情头 -->
<table class="cart-header">
<tbody>
<tr>
<td class="cart-col-select col-md-3 col-xs-3 col-sm-3">
<div class="cart-select-all JSelectAll">
<div class="mz-checkbox"></div>
<span class="cart-select-title">全选</span>
</div>
</td>
<td class="cart-col-name col-md-3 hidden-xs hidden-sm">商品</td>
<td class="cart-col-price col-md-2 hidden-xs hidden-sm">单价(元)</td>
<td class="cart-col-number col-md-2 hidden-xs hidden-sm">数量</td>
<td class="cart-col-total col-md-1 hidden-xs hidden-sm">小计(元)</td>
<td class="cart-col-ctrl col-md-1 hidden-xs hidden-sm">操作</td>
</tr>
</tbody>
</table><!-- 购物车详情头 E-->
<!-- 购物清单信息列表 -->
<div class="cart-merchant-list">
<div class="cart-merchant">
<table class="cart-merchant-body">
<tbody>
{% for shop in request.session.shoplist.values %}
<tr class="cart-product">
<td class="cart-col-select col-md-3 col-xs-4 col-sm-4">
<div class="mz-checkbox" gid="{{shop.id}}" price="{% widthratio shop.price 1 shop.m %}"></div>
<a href="{% url 'detail' shop.id %}" class="cart-product-link" target="_blank">
<img src="/static/goods/s_{{ shop.picname }}" class="cart-product-img" alt="{{ shop.goods }}" width="50">
</a>
</td>
<td class="cart-col-name col-md-3 col-xs-8 col-sm-8">
<a href="{% url 'detail' shop.id %}" class="cart-product-link" target="_blank">
<p>{{ shop.goods }}</p>
</a>
<p class="">
<span class="cart-product-price">{{ shop.price }}</span>
</p>
<div class="cart-col-number">
<div class="cart-product-number-adder">
<p class="cart-product-number-max show"></p>
<div class="mz-adder">
<button class="mz-adder-subtract disabled"></button>
<div class="mz-adder-num"><input class="mz-adder-input" value="1" type="text"></div>
<button class="mz-adder-add"></button>
</div>
</div>
</div>
</td>
<td class="cart-col-price col-md-2 hidden-xs hidden-sm">
<p>
<span class="cart-product-price">{{ shop.price}}</span>
</p>
</td>
<td class="cart-col-number col-md-2 hidden-xs hidden-sm">
<div class="cart-product-number-adder">
<p class="cart-product-number-max show"></p>
<div class="mz-adder">
<button onclick="window.location='{% url 'cart_change' %}?gid={{shop.id}}&num={{shop.m|add:-1}}'" class="mz-adder-subtract"></button>
<div class="mz-adder-num"><input class="mz-adder-input" value="{{ shop.m }}" onblur="window.location='{% url 'cart_change' %}?gid={{shop.id}}&num='+this.value" type="text"></div>
<button onclick="window.location='{% url 'cart_change' %}?gid={{shop.id}}&num={{shop.m|add:1}}'" class="mz-adder-add"></button>
</div>
</div>
</td>
<td class="cart-col-total col-md-1 hidden-xs hidden-sm">
<span class="cart-product-price total">{% widthratio shop.price 1 shop.m %}</span>
</td>
<td class="cart-col-ctrl col-md-1 hidden-xs hidden-sm">
<a href="{% url 'cart_del' shop.id %}" title="删除">
<div class="cart-product-remove">
<span class="glyphicon glyphicon-remove"></span>
</div>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div><!-- 购物清单信息列表 E-->
</div>
<!-- 结算详情 -->
<div class="cart-footer" id="cartFooter">
<div class="container">
<div class="cart-footer-left col-md-6 col-xs-4 col-sm-4">
<div class="cart-select-all JSelectAll" data-mdesc="全选按钮" data-mtype="store_cart_all">
<div class="mz-checkbox"></div>
<span class="cart-select-title">全选</span>
</div>
<!-- <span class="cart-remove-selected" id="removeSelected">删除选中的商品</span> -->
<span class="cart-footer-count">
共
<span class="cart-footer-num" id="totalCount"></span>
件商品
</span>
<div class="mz-btn btn-danger" onclick="window.location='{% url 'cart_clear' %}'" id="cartSubmit">清空购物车</div>
</div>
<div class="cart-footer-right col-md-5 col-md-offset-1 col-sm-offset-2 col-xs-8 col-sm-6">
<span class="cart-footer-sum">
<span class="cart-footer-text">已优惠</span>
<span class="cart-footer-num red" id="totalDiscount">0.00</span>
<span class="cart-footer-text">元, 合计(不含运费):</span>
<span class="cart-footer-total" id="totalPrice">0.0</span>
</span>
<div onclick="window.location='/orders/add?ids='+loadTotal().join(',')" class="mz-btn btn-success" id="cartSubmit">去结算</div>
</div>
</div>
</div><!-- 结算详情 E-->
</div>
{% endblock %}
{% block myjs %}
//全选
allSelect();
//登录图片鼠标经过
//topLogin();
//商品数量加减
//cartAddMin()
loadTotal();
var gidlist = [];
{% endblock %}
- 4.2. 订单地址填写模板:/templates/web/ordersadd.html
{% extends "web/base.html" %}
{% load static from staticfiles %}
{% block mylink %}
<link rel="stylesheet" type="text/css" href="{% static 'web/css/cart.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'web/css/cart-app.css' %}">
{% endblock %}
{% block mainbody %}
<form action="{% url 'orders_confirm' %}" method="post">
{% csrf_token %}
<div class="mainbody cart" style="margin-top: 80px;">
<div class="container">
<!-- 下订单的1/3步骤 -->
<table class="cart-header">
<tbody>
<tr>
<td class="cart-col-select col-md-12">
当前位置: 订单处理 > 1/3 填写收货地址:
</td>
</tr>
</tbody>
</table><!-- 下订单的1/3步骤 E-->
<!-- 订单物流信息 -->
<div class="cart-merchant-list">
<div class="cart-merchant">
<table class="cart-merchant-body">
<tbody>
<tr class="cart-product" style="height:60px;border:none;">
<td class="cart-col-select col-md-2 col-xs-3 col-sm-3" style="text-align: right;">
联系人:
</td>
<td class="cart-col-name col-md-3 col-xs-4 col-sm-4">
<input type="text" name="linkman" value="{{ request.session.vipuser.name}}" size="40"/>
</td>
</tr>
<tr class="cart-product" style="height:60px;border:none;">
<td class="cart-col-select col-md-2 col-xs-3 col-sm-3" style="text-align: right;">
收货地址:
</td>
<td class="cart-col-name col-md-3 col-xs-4 col-sm-4">
<input type="text" name="address" value="{{ request.session.vipuser.address}}" size="40"/>
</td>
</tr>
<tr class="cart-product" style="height:60px;border:none;">
<td class="cart-col-select col-md-2 col-xs-3 col-sm-3" style="text-align: right;">
联系电话:
</td>
<td class="cart-col-name col-md-3 col-xs-4 col-sm-4">
<input type="text" name="phone" value="{{ request.session.vipuser.phone}}" size="40"/>
</td>
</tr>
<tr class="cart-product" style="height:60px;border:none;">
<td class="cart-col-select col-md-2 col-xs-3 col-sm-3" style="text-align: right;">
邮编:
</td>
<td class="cart-col-name col-md-3 col-xs-4 col-sm-4">
<input type="text" name="code" value="{{ request.session.vipuser.code}}" size="40"/>
</td>
</tr>
<tr class="cart-product" style="height:60px;border:none;">
<td class="cart-col-select col-md-2 col-xs-3 col-sm-3" style="text-align: right;">
总金额:
</td>
<td class="cart-col-name col-md-3 col-xs-4 col-sm-4">
<input type="text" disabled value="{{ request.session.total }} 元" name="linkman" size="40"/>
</td>
</tr>
</tbody>
</table>
</div>
</div><!-- 订单物流信息 E-->
</div>
<!-- 操作按钮 -->
<div class="cart-footer" id="cartFooter">
<div class="container">
<div class="cart-footer-right col-md-12" style="text-align:center">
<div onclick="window.history.go(-1)" class="mz-btn btn-success" id="cartSubmit">返回</div>
<button type="submit" class="mz-btn btn-success" id="cartSubmit">下一步</button>
</div>
</div>
</div><!-- 操作按钮 E-->
</div></form>
{% endblock %}
- 4.3. 订单确认模板:/templates/web/ordersconfirm.html
{% extends "web/base.html" %}
{% load static from staticfiles %}
{% block mylink %}
<link rel="stylesheet" type="text/css" href="{% static 'web/css/cart.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'web/css/cart-app.css' %}">
{% endblock %}
{% block mainbody %}
<form action="{% url 'orders_insert' %}" method="post">
{% csrf_token %}
<div class="mainbody cart" style="margin-top: 80px;padding-bottom:5px;">
<div class="container">
<!-- 下订单的2/3步骤 -->
<table class="cart-header">
<tbody>
<tr>
<td class="cart-col-select col-md-12">
当前位置: 订单处理 > 2/3 确认订单信息:
</td>
</tr>
</tbody>
</table><!-- 下订单的2/3步骤 E-->
<!-- 订单通信信息 -->
<div class="cart-merchant-list">
<div class="cart-merchant">
<table class="cart-merchant-body">
<tbody>
<tr class="cart-product" style="height:60px;border:none;">
<td class="cart-col-select col-md-2 col-xs-3 col-sm-3" style="text-align: right;">
联系人:
</td>
<td class="cart-col-name col-md-3 col-xs-4 col-sm-4">
<input readonly type="text" name="linkman" value="{{ request.POST.linkman}}" size="40"/>
</td>
</tr>
<tr class="cart-product" style="height:60px;border:none;">
<td class="cart-col-select col-md-2 col-xs-3 col-sm-3" style="text-align: right;">
收货地址:
</td>
<td class="cart-col-name col-md-3 col-xs-4 col-sm-4">
<input readonly type="text" name="address" value="{{ request.POST.address}}" size="40"/>
</td>
</tr>
<tr class="cart-product" style="height:60px;border:none;">
<td class="cart-col-select col-md-2 col-xs-3 col-sm-3" style="text-align: right;">
联系电话:
</td>
<td class="cart-col-name col-md-3 col-xs-4 col-sm-4">
<input readonly type="text" name="phone" value="{{ request.POST.phone}}" size="40"/>
</td>
</tr>
<tr class="cart-product" style="height:60px;border:none;">
<td class="cart-col-select col-md-2 col-xs-3 col-sm-3" style="text-align: right;">
邮编:
</td>
<td class="cart-col-name col-md-3 col-xs-4 col-sm-4">
<input readonly type="text" name="code" value="{{ request.POST.code}}" size="40"/>
</td>
</tr>
<tr class="cart-product" style="height:60px;border:none;">
<td class="cart-col-select col-md-2 col-xs-3 col-sm-3" style="text-align: right;">
总金额:
</td>
<td class="cart-col-name col-md-3 col-xs-4 col-sm-4">
<input type="text" disabled value="{{ request.session.total }} 元" name="linkman" size="40"/>
</td>
</tr>
</tbody>
</table>
</div>
</div><!-- 订单通信信息 E-->
</div>
<!-- 操作按钮 -->
<div class="cart-footer" id="cartFooter">
<div class="container">
<div class="cart-footer-right col-md-12" style="text-align:center">
<div onclick="window.history.go(-1)" class="mz-btn btn-success" id="cartSubmit">返回修改</div>
<button type="submit" class="mz-btn btn-success" id="cartSubmit">确认下单</button>
</div>
</div>
</div><!-- 操作按钮 E-->
</div></form>
<div class="mainbody cart" style="padding-bottom:15px;">
<div class="container">
<!-- 订单信息头 -->
<table class="cart-header">
<tbody>
<tr>
<td class="cart-col-name col-md-3 hidden-xs hidden-sm">商品</td>
<td class="cart-col-name col-md-3 hidden-xs hidden-sm">图片</td>
<td class="cart-col-price col-md-2 hidden-xs hidden-sm">单价(元)</td>
<td class="cart-col-number col-md-2 hidden-xs hidden-sm">数量</td>
<td class="cart-col-total col-md-1 hidden-xs hidden-sm">小计(元)</td>
</tr>
</tbody>
</table><!-- 订单信息头 E-->
<!-- 订单确认信息 -->
<div class="cart-merchant-list">
<div class="cart-merchant">
<table class="cart-merchant-body">
<tbody>
{% for shop in request.session.orderslist.values %}
<tr class="cart-product" style="height:100px;">
<td class="cart-col-name col-md-3 hidden-xs hidden-sm">
<p>
<div class="mz-adder-num">{{ shop.goods }}</div>
</p>
</td>
<td class="cart-col-name col-md-3 hidden-xs hidden-sm">
<p>
<div class="mz-adder-num"><img src="/static/goods/s_{{ shop.picname }}" alt="{{ shop.goods }}" width="50"></div>
</p>
</td>
<td class="cart-col-price col-md-2 hidden-xs hidden-sm">
<p>
<span class="cart-product-price">{{ shop.price}}</span>
</p>
</td>
<td class="cart-col-number col-md-2 hidden-xs hidden-sm">
<p>
<div class="mz-adder-num">{{ shop.m }}</div>
</p>
</td>
<td class="cart-col-total col-md-1 hidden-xs hidden-sm">
<span class="cart-product-price total">{% widthratio shop.price 1 shop.m %}</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div><!-- 订单确认信息 E-->
</div>
</div>
{% endblock %}
- 4.4. 订单信息提示模板:/templates/web/ordersinfo.html
{% extends "web/base.html" %}
{% load static from staticfiles %}
{% block mylink %}
<link rel="stylesheet" type="text/css" href="{% static 'web/css/cart.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'web/css/cart-app.css' %}">
{% endblock %}
{% block mainbody %}
<div class="mainbody cart" style="margin-top: 80px;">
<div class="container">
<!-- 下订单的3/3步骤 -->
<table class="cart-header">
<tbody>
<tr>
<td class="cart-col-select col-md-12">
当前位置: 订单处理 > 3/3 订单完成:
</td>
</tr>
</tbody>
</table><!-- 下订单的3/3步骤 E-->
<!-- 下订单提示信息 -->
<div class="cart-merchant-list">
<div class="cart-merchant text-center" style="font-size:30px;color:#fc0;line-height:100px;">
{{ info }}
</div>
</div><!-- 下订单提示信息 E-->
</div>
<!-- 操作按钮 -->
<div class="cart-footer" id="cartFooter">
<div class="container">
<div class="cart-footer-right col-md-12" style="text-align:center">
<div onclick="window.history.go(-1)" class="mz-btn btn-success" id="cartSubmit">返回</div>
<a href="{% url 'index' %}" class="mz-btn btn-success">首页</a>
</div>
</div>
</div><!-- 操作按钮 E-->
</div>
{% endblock %}