如果直接阅读本文,您可能有些不知所云,这是因为我用很多篇幅讲了一个事情,如果想知道上下文,那么建议您从本专栏第22章看起:Python3开发–22–了解Django框架

一、商品详细的业务逻辑

所有网页展示的商品信息都设置了商品详细页的地址链接,商品详细页用于展示某一商品的主图、名称、规格、数量、详细介绍、购买按钮、收藏按钮等,并在商品详细介绍的左侧设置了热销商品列表。

商品详细页分为5个功能区,分别是:商品搜索功能、网站导航、商品基本信息、商品详细介绍、热销推荐。

修改代码:commodity/views.py

from django.shortcuts import render
from .models import *

def detailView(request, id):
    title = '商品介绍'
    classContent = 'datails'
    commoditys = CommodityInfos.objects.filter(id=id).first()
    items = CommodityInfos.objects.exclude(id=id).order_by('-sold')[:5]
    likesList = request.session.get('likes', [])
    likes = True if id in likesList else False
    return render(request, 'details.html', locals())

二、商品详细的数据渲染

视图函数detailView使用模板文件details.html作为响应内容,在该模板文件中,需要使用变量commoditysitems进行数据渲染和展示。

修改代码:templates/details.html

<!-- 调用模板文件base.html -->
{% extends 'base.html' %}
{% load static %}
<!-- 重写接口content -->
{% block content %}
    <div class="data-cont-wrap w1200">
      <div class="crumb">
        <!-- 在首页中设置路由 -->
        <a href="{% url 'index:index' %}">首页</a>
        <span>></span>
        <a href="{% url 'commodity:commodity' %}">所有商品</a>
        <span>></span>
        <a href="javascript:;">产品详情</a>
      </div>
        
      <!-- 使用变量commoditys生成商品的基本信息 -->
      <div class="product-intro layui-clear">
        <div class="preview-wrap">
          <img height="300" width="300" src="{{ commoditys.img.url }}">
        </div>
        <div class="itemInfo-wrap">
          <div class="itemInfo">
            <div class="title">
              <h4>{{ commoditys.name }}</h4>
                {% if likes %}
              <span id="collect"><i class="layui-icon layui-icon-rate-solid"></i>收藏</span>
                {% else %}
              <span id="collect"><i class="layui-icon layui-icon-rate"></i>收藏</span>
                {% endif %}
            </div>
            <div class="summary">
              <p class="reference"><span>参考价</span> <del>¥{{ commoditys.price|floatformat:'2' }}</del></p>
              <p class="activity"><span>活动价</span><strong class="price"><i>¥</i>{{ commoditys.discount|floatformat:'2' }}</strong></p>
              <p class="address-box"><span>送    至</span><strong class="address">广东  广州  天河区</strong></p>
            </div>
            <div class="choose-attrs">
              <div class="color layui-clear"><span class="title">规    格</span> <div class="color-cont"><span class="btn active">{{ commoditys.sezes }}</span></div></div>
              <div class="number layui-clear"><span class="title">数    量</span><div class="number-cont">
                  <span class="cut btn">-</span>
                  <input onkeyup="if(this.value.length==1){this.value=this.value.replace(/[^1-9]/g,'')}else{this.value=this.value.replace(/\D/g,'')}" onafterpaste="if(this.value.length==1){this.value=this.value.replace(/[^1-9]/g,'')}else{this.value=this.value.replace(/\D/g,'')}" maxlength="4" type="" id="quantity" value="1">
                  <span class="add btn">+</span></div></div>
            </div>
            <div class="choose-btns">
              <a class="layui-btn  layui-btn-danger car-btn">
                  <i class="layui-icon layui-icon-cart-simple"></i>加入购物车</a>
            </div>
          </div>
        </div>
      </div>
        
      <!-- 使用变量item生成商品的热销推荐,每个商品只展示商品主图、排名和折后价 -->
      <div class="layui-clear">
        <div class="aside">
          <h4>热销推荐</h4>
          <div class="item-list">
            {% for item in items %}
            <div class="item">
              <a href="{% url 'commodity:detail' item.id %}">
              <img height="280" width="280" src="{{ item.img.url }}">
              </a>
              <p>
                  <span title="{{ item.name }}">
                      {% if item.name|length > 15 %}
                        {{ item.name|slice:":15" }}...
                      {% else %}
                        {{ item.name|slice:":15" }}
                      {% endif %}
                  </span>
                  <span class="pric">¥{{ item.discount|floatformat:'2' }}</span>
              </p>
            </div>
            {% endfor %}
          </div>
        </div>
      
        <!-- 使用变量commoditys的字段details的url属性生成商品详细图的地址链接 -->
        <div class="detail">
          <h4>详情</h4>
          <div class="item">
            <img width="800" src="{{ commoditys.details.url }}">
          </div>
        </div>
      </div>
    </div>
{% endblock content %}

<!-- 重写模板文件base.html的接口script,一共编写了3个javascript脚本 -->
{% block script %}
  layui.config({
    base: '{% static 'js/' %}'
  }).use(['mm','jquery'],function(){
      var mm = layui.mm,$ = layui.$;
      var cur = $('.number-cont input').val();
      $('.number-cont .btn').on('click',function(){
        if($(this).hasClass('add')){
          cur++;
        }else{
          if(cur > 1){
            cur--;
          }
        }
        $('.number-cont input').val(cur)
      })

    $('.layui-btn.layui-btn-danger.car-btn').on('click',function(){
        var quantity = $("#quantity").val();
        window.location = "{% url 'shopper:shopcart' %}?id={{ commoditys.id }}&quantity=" + quantity
    });

    $('#collect').on('click',function(){
        var url = "{% url 'commodity:collect' %}?id={{ commoditys.id }}"
        $.get(url ,function(data,status){
            if (data.result=="收藏成功"){
                $('#collect').find("i").removeClass("layui-icon-rate")
                $('#collect').find("i").addClass("layui-icon-rate-solid")
            }
            alert(data.result);
        });
    });
  });

{% endblock script %}

三、商品收藏

在模板文件details.html中,通过重写模板文件base.html的接口script,并对商品收藏按钮绑定了事件触发函数,它是向路由collect发送HTTP的GET请求,这个HTTP请求过程是在JavaScript代码中完成的。

1、修改代码:commodity/urls.py

from django.urls import path
from .views import *

urlpatterns = [
    # 第一个参数用于设置具体的路由地址
    # 第二个参数是指向index应用的views.py的某个视图函数
    # 第三个参数用于命名路由地址,是个可选参数
    path('.html', commodityView, name='commodity'),
    # 设置了路由变量id,该变量ID以整数型表示
    path('/detail.<int:id>.html', detailView, name='detail'),
    # 新增,定义路由collect
    path('/collect.html', collectView, name='collect')
]

2、修改代码:commodity/views.py

from .models import *
from django.http import JsonResponse
from django.db.models import F

def collectView(request):
    # 获取当前商品主键ID
    id = request.GET.get('id', '')
    # 设置响应内容
    result = {"result": "已收藏"}
    likes = request.session.get('likes', [])
    # 如果商品未收藏,则执行商品收藏
    if id and not int(id) in likes:
        # 对商品的收藏数量执行自增加1
        CommodityInfos.objects.filter(id=id).update(likes=F('likes')+1)
        result['result'] = "收藏成功"
        request.session['likes'] = likes + [int(id)]
    return JsonResponse(result)

四、总结

1、commodity/views.py经过多次修改扩充,我们现在来看看它的全貌

from django.shortcuts import render
from django.core.paginator import Paginator
from django.core.paginator import EmptyPage
from django.core.paginator import PageNotAnInteger
from .models import *
from django.http import JsonResponse
from django.db.models import F

def detailView(request, id):

    title = '商品介绍'
    classContent = 'datails'
    commoditys = CommodityInfos.objects.filter(id=id).first()
    items = CommodityInfos.objects.exclude(id=id).order_by('-sold')[:5]
    likesList = request.session.get('likes', [])
    likes = True if id in likesList else False
    return render(request, 'details.html', locals())

def collectView(request):
    # 获取当前商品主键ID
    id = request.GET.get('id', '')
    # 设置响应内容
    result = {"result": "已收藏"}
    likes = request.session.get('likes', [])
    # 如果商品未收藏,则执行商品收藏
    if id and not int(id) in likes:
        # 对商品的收藏数量执行自增加1
        CommodityInfos.objects.filter(id=id).update(likes=F('likes')+1)
        result['result'] = "收藏成功"
        request.session['likes'] = likes + [int(id)]
    return JsonResponse(result)

def commodityView(request):
    # 对应模板base.html的模板变量title和classContent
    title = '商品列表'
    classContent = 'commoditys'

    # 根据模型Types生成商品分类列表
    firsts = Types.objects.values('firsts').distinct()
    typesList = Types.objects.all()

    # 获取请求参数
    # shaixuan是某个分页商品的信息,以整型格式表现
    shaixuan = request.GET.get('shaixuan', '')
    # paixu是设置商品的排序方式
    paixu = request.GET.get('paixu', 'sold')
    # fenye是设置商品信息的页数,默认页数等于1
    fenye = request.GET.get('fenye', 1)
    # chaxun是商品搜索功能的关键字
    chaxun = request.GET.get('chaxun', '')

    # 根据请求参数查询商品信息
    commodityInfos = CommodityInfos.objects.all()
    if shaixuan:
        types = Types.objects.filter(id=shaixuan).first()
        commodityInfos = commodityInfos.filter(types=types.seconds)
    if paixu:
        commodityInfos = commodityInfos.order_by('-' + paixu)
    if chaxun:
        commodityInfos = commodityInfos.filter(name__contains=chaxun)

    # 分页功能
    paginator = Paginator(commodityInfos, 6)
    try:
        pages = paginator.page(fenye)
    except PageNotAnInteger:
        pages = paginator.page(1)
    except EmptyPage:
        pages = paginator.page(paginator.num_pages)

    return render(request, 'commodity.html', locals())

2、看看我们本节动过哪些代码文件

python商品管理 python商城项目_html