11. 项目实战前台之商品展示

  • 本节将实现商城项目前台:分类导航、商品列表和商品详情的功能实现,关于商城首页的商品信息展示将会在项目的后期完成。

  • 分类导航:将商品的一级类别信息作为页面的导航链接信息显示

  • 商品列表:在/list/list/页号请求中分类分页展示商品信息

  • 商品详情:在/detail/gid号请求中展示指定商品id号的商品信息

  • 商城首页:输出部分最新商品、热卖商品、推荐商品或点击量最高的信息,由于目前数据信息不完善,故后期完成。

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

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

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

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


from django.conf.urls import url

from web.views import index

urlpatterns = [
    #网站前台
    url(r'^$',index.index,name="index"), #首页
    url(r'^list$',index.lists,name="list"), #商品列表展示
    #url(r'^list/(?P<pIndex>[0-9]+)$',index.lists,name="list"), #分页商品列表展示
    url(r'^detail/(?P<gid>[0-9]+)$',index.detail,name="detail"), #商品详情

    # 会员及个人中心等路由配置
    url(r'^login$', index.login, name="login"),
    url(r'^dologin$', index.dologin, name="dologin"),
    url(r'^logout$', index.logout, name="logout"),

]

 (2). 编辑视图文件

  • 新建视图文件:myobject/web/views/index.py 视图文件,并进行编辑
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import redirect
from django.core.urlresolvers import reverse
from django.core.paginator import Paginator

from common.models import Users,Types,Goods

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

# =============商品展示========================
def index(request):
    '''项目前台首页'''
    context = loadinfo(request)
    return render(request,"web/index.html",context)

def lists(request,pIndex=1):
    '''商品列表页(搜索&分页)'''
    context = loadinfo(request)
    #获取商品信息查询对象
    mod = Goods.objects
    mywhere=[] #定义一个用于存放搜索条件列表

    #判断添加搜索条件
    tid = int(request.GET.get('tid',0))
    if tid > 0:
        list = mod.filter(typeid__in=Types.objects.only('id').filter(pid=tid))
        mywhere.append("tid="+str(tid))
    else:
        list = mod.filter()

    #获取、判断并封装关keyword键搜索
    kw = request.GET.get("keyword",None)
    if kw:
        # 查询商品名中只要含有关键字的都可以
        list = list.filter(goods__contains=kw)
        mywhere.append("keyword="+kw)

    #执行分页处理
    pIndex = int(pIndex)
    page = Paginator(list,5) #以5条每页创建分页对象
    maxpages = page.num_pages #最大页数
    #判断页数是否越界
    if pIndex > maxpages:
        pIndex = maxpages
    if pIndex < 1:
        pIndex = 1
    list2 = page.page(pIndex) #当前页数据
    plist = page.page_range   #页码数列表

    #封装信息加载模板输出
    context['goodslist'] = list2
    context['plist'] = plist
    context['pIndex'] = pIndex
    context['maxpages'] = maxpages
    context['mywhere'] = mywhere
    context['tid'] = int(tid)
    return render(request,"web/list.html",context)

def detail(request,gid):
    '''商品详情页'''
    context = loadinfo(request)
    #加载商品详情信息
    ob = Goods.objects.get(id=gid)
    ob.clicknum += 1 # 点击量加1
    ob.save()
    context['goods'] = ob
    return render(request,"web/detail.html",context)

# ==============前台会员登录====================
# 略(上节中已编写)... ...

(3). 编写模板文件

  • 3.1. 打开父类模板:/templates/web/base.html ,编辑导航栏代码
    ...
    <ul class="nav navbar-nav navbar-right layout-header-nav clearfix">
        <li class="layout-header-nav-item">
          <a href="{% url 'index' %}" class="layout-header-nav-link">网站首页</a><p class="line-top hidden-xs"></p>
        </li>
        <li class="layout-header-nav-item"><a href="{% url 'list' %}" class="layout-header-nav-link">全部商品</a></li>

        {% for type in typelist %}
        <li class="layout-header-nav-item">
          <a href="{% url 'list' %}?tid={{ type.id }}" class="layout-header-nav-link">{{ type.name }}</a>
        </li>
        {% endfor %}

        <li class="layout-header-nav-item"><a href="#" class="layout-header-nav-link">社区</a></li>                          
    </ul>     
    ...
  • 3.2. 商品列表信息显示模板:/templates/web/list.html
...
      <!-- 商品列表 -->
      <div class="goods-list">
        <div class="row">
         {% for goods in goodslist %}
          <div class="col-md-3 col-sm-6 col-xs-6">
            <div class="gl-item">
              <div class="compare-btn-list" >
                  <i class="iconfont  icon-duibi compare-duibi"></i>
                  <span class="hidden-xs hidden-sm">对比</span>
              </div>
              <div class="gl-item-wrap">
                <!-- Tab panes -->
                <div class="tab-content">
                  <div role="tabpanel" class="tab-pane active mod-pic" id="list-p1">
                    <a href="{% url 'detail' goods.id %}">
                      <img class="lazy j-modProduct" src="/static/goods/m_{{ goods.picname }}" width="220" height="220">
                    </a>
                  </div>
                </div>

                <!-- Nav tabs -->
                <div class="item-slide j-pro-wrap  hidden-xs hidden-sm">
                  <ul class="nav nav-tabs  " role="tablist">
                    <li role="presentation" class="active">
                      <a href="#list-p1" aria-controls="list-p1" role="tab" data-toggle="tab">
                        <img class="lazy"  src="/static/goods/s_{{ goods.picname }}" style="display: inline;" width="40" height="40">
                      </a>
                    </li>
                  </ul>
                </div>
                <div class="slide-btn j-modBtns" style="display: none;">
                    <span  class="prev iconfont disabled"></span>
                    <span  class="next iconfont"></span>
                </div>

                <h2>{{ goods.goods}}</h2>
                <h3 class="red" title="双11促销:满500,减100!">
                双11促销:满500,减100!
                </h3>
                <dd class="mod-price">
                    <span></span>
                    <span class="vm-price">{{ goods.price }}</span>
                    <span class="vm-start"></span>
                </dd>
              </div>
            </div>
          </div>
         {% endfor %}
        </div>
      </div>
      <!-- 商品列表 -->

      <nav aria-label="Page navigation" class="text-center">
        <ul class="pagination">
          <li>
            <a href="{% url 'list' pIndex|add:-1 %}?{{ mywhere|join:'&' }}" aria-label="Previous">
              <span aria-hidden="true">&laquo;</span>
            </a>
          </li>
          {% for p in plist %}
            <li {% if pIndex == p %}class="active"{% endif %}>
              <a href="{% url 'list' p %}?{{ mywhere|join:'&' }}">{{p}}</a>
            </li>
          {% endfor %}
          <li>
            <a href="{% url 'list' pIndex|add:1 %}?{{ mywhere|join:'&' }}" aria-label="Next">
              <span aria-hidden="true">&raquo;</span>
            </a>
          </li>
        </ul>
      </nav>
...
  • 3.3. 商品详情信息显示模板:/templates/web/detail.html
    在详情模板中输出部分商品信息即可