13. 项目实战前台之下单操作

  • 本节将实现商城项目中会员下单操作模块:填写收货地址、确认订单信息和执行下单等操作。

 

 

(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 %}