12. 项目实战前台之购物车实战

  • 本节将实现商城项目前台的购物车管理模块:添加、浏览、删除、修改和清空等购物车操作。

 

(1). 开发前的准备工作:

  • 在数据库 shopdb 中已存在数据表goods,并且内有测试数据。

  • 默认开启了session,并且执行了数据迁移,数据库中已存在django_session表。

  • 在common应用目录中的myobject/common/models.py 模型文件中,已存在Goods模型类的定义。

  • 并且在Goods模型类中已经定义了toDict(self)方法:

 # 注意:返回此商品的字典格式
 def toDict(self):
        return {'id':self.id,'typeid':self.typeid,'goods':self.goods,'company':self.company,'price':self.price,'picname':self.picname,'store':self.store,'num':self.num,'clicknum':self.clicknum,'state':self.state}
  • 在商品详情页中处理立即购买按钮,完成向添加购物车操作的传值和跳转:
    <form action="{% url 'cart_add' goods.id %}" method="post">
      {% csrf_token %}
      <div class="property-buy">
        <p class="vm-message" id="J_message"></p>
        <dl class="property-buy-quantity">
            <dt class="vm-metatit"><span class="s-space"></span><span class="s-space"></span>量:</dt>
            <dd class="clearfix">
                <div class="mod-control">
                   <a title="减少" href="javascript:;" class="vm-minus disabled">-</a>
                   <input value="1" name="m" id="J_quantity" data-max="5" type="text">
                   <a title="增加" href="javascript:;" class="vm-plus">+</a>
                </div>
            </dd>
        </dl>
        <div class="property-buy-action">
            <button data-mtype="store_de_buy" type="submit" id="J_btnBuy" class="btn btn-danger btn-lg mr20">立即购买</button>
            <a data-mtype="store_de_cart" href="javascript:void(0);" id="J_btnAddCart" class="btn btn-primary btn-lg hide" style="display:inline-block;"><i></i>加入购物车</a>
            <span class="vm-service" id="J_panicBuyingWrap"></span>
        </div>
      </div>
    </form>

(2). 项目urls路由信息配置

  • 打开根路由文件:myobject/web/urls.py路由文件,编辑路由配置信息:

from django.conf.urls import url

from web.views import index,cart

urlpatterns = [
    #网站前台
    # ... ...

    # 会员及个人中心等路由配置
    # ... ...

    # 购物车路由
    url(r'^cart$', cart.index,name='cart_index'), #浏览购物车
    url(r'^cart/add/(?P<gid>[0-9]+)$', cart.add,name='cart_add'), #添加购物车
    url(r'^cart/del/(?P<gid>[0-9]+)$', cart.delete,name='cart_del'), #从购物车中删除一个商品
    url(r'^cart/clear$', cart.clear,name='cart_clear'), #清空购物车
    url(r'^cart/change$', cart.change,name='cart_change'), #更改购物车中商品数量

]

 (3). 编辑视图文件

  • 新建视图文件:myobject/web/views/cart.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

# 公共信息加载
def loadinfo(request):
    '''公共信息加载'''
    context = {}
    lists = Types.objects.filter(pid=0)
    context['typelist'] = lists
    return context

def index(request):
    '''浏览购物车'''
    context = loadinfo(request)
    if 'shoplist' not in request.session:
        request.session['shoplist']={}
    return render(request,"web/cart.html",context)

def add(request,gid):
    '''在购物车中放入商品信息'''
    #获取要放入购物车中的商品信息
    goods = Goods.objects.get(id=gid)
    shop = goods.toDict();
    shop['m'] = int(request.POST.get('m',1))  #添加一个购买量属性m
    #从session获取购物车信息,没有默认空字典
    shoplist = request.session.get('shoplist',{})
    #判断此商品是否在购物车中
    if gid in shoplist:
        #商品数量加
        shoplist[gid]['m']+=shop['m']
    else:
        #新商品添加
        shoplist[gid]=shop

    #将购物车信息放回到session
    request.session['shoplist'] = shoplist

    #重定向到浏览购物车页
    return redirect(reverse('cart_index'))
    #return render(request,"web/cart.html")

def delete(request,gid):
    '''删除一个商品'''
    shoplist = request.session['shoplist']
    del shoplist[gid]
    request.session['shoplist'] = shoplist
    return redirect(reverse('cart_index'))

def clear(request):
    '''清空购物车'''
    context = loadinfo(request)
    request.session['shoplist'] = {}
    return render(request,"web/cart.html",context)

def change(request):
    '''更改购物车中的商品信息'''
    #context = loadinfo(request)
    shoplist = request.session['shoplist']
    #获取信息
    shopid = request.GET.get('gid','0')
    num = int(request.GET['num'])
    if num<1:
        num = 1
    shoplist[shopid]['m'] = num #更改商品数量
    request.session['shoplist'] = shoplist
    return redirect(reverse('cart_index'))
    #return render(request,"web/cart.html",context)

(4). 编写模板文件

  • 4.1. 打开父类模板:/templates/web/base.html ,编辑导航栏代码
    ...
    <li class="layout-header-service-item layout-header-service-cart" id="layoutHeaderCart">
        <a class="layout-header-service-link" href="{% url 'cart_index' %}" data-mtype="wmz_public_yt_cart">
            <i class="glyphicon glyphicon-shopping-cart"></i>
            <span class="layout-header-service-cart-num">{{ request.session.shoplist|length}}</span>
        </a>
    </li>
    ...
  • 4.2. 购物车页面信息显示模板:/templates/web/cart.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">
      <!-- 购物车详情头 -->
      <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 %}