IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 美多商城之商品(商品列表页) -> 正文阅读

[人工智能]美多商城之商品(商品列表页)

四、商品列表页

4.1 商品列表页分析

4.1.1. 商品列表页组成结构分析

1.商品频道分类

  • 已经提前封装在contents.utils.py文件中,直接调用即可。

2.面包屑导航

  • 可以使用三级分类ID,查询出该类型商品的三级分类数据。

3.排序和分页

  • 无论如何排序和分页,商品的分类不能变。
  • 排序时需要知道当前排序方式。
  • 分页时需要知道当前分页的页码,且每页五条商品记录。

4.热销排行

  • 热销排行中的商品分类要和排序、分页的商品分类一致。
  • 热销排行是查询出指定分类商品销量前二的商品。
  • 热销排行使用Ajax实现局部刷新的效果。

4.1.2. 商品列表页接口设计和定义

1.请求方式

选项方案
请求方法GET
请求地址/list/(?P<category_id>\d+)/(?P<page_num>\d+)/?sort=排序方式
# 按照商品创建时间排序
http://www.meiduo.site:8000/list/115/1/?sort=default
# 按照商品价格由低到高排序
http://www.meiduo.site:8000/list/115/1/?sort=price
# 按照商品销量由高到低排序
http://www.meiduo.site:8000/list/115/1/?sort=hot

总路由:

?子路由:

from django.conf.urls import url
from . import views

urlpatterns = [
    #  商品列表
    url(r'^list/(?P<category_id>\d+)/(?P<page_num>\d+)/$', views.ListView.as_view(), name='list'),

]

2.请求参数:路径参数 和 查询参数

参数名类型是否必传说明
category_idstring商品分类ID,第三级分类
page_numstring当前页码
sortstring排序方式

3.响应结果:HTML

list.html

【把list.html和list.js文件复制到项目中】

4.接口定义

goods.views.py

from django.shortcuts import render
from django.views import View


# Create your views here.
class ListView(View):
    """商品列表页"""

    def get(self, request, category_id, page_num):
        """提供商品列表页"""
        return render(request, 'list.html')

4.2 列表页面包屑导航

重要提示:路径参数category_id是商品第三级分类

4.2.1. 查询列表页面包屑导航数据

提示: 对包屑导航数据的查询进行封装,方便后续直接使用。

goods.utils.py

def get_breadcrumb(category):
    """
    获取面包屑导航
    :param category: 商品类别
    :return: 面包屑导航字典
    """
    breadcrumb = dict(
        cat1='',
        cat2='',
        cat3=''
    )
    if category.parent is None:
        # 当前类别为一级类别
        breadcrumb['cat1'] = category
    elif category.subs.count() == 0:  # 此时若没有子集,则为3级
        # 当前类别为三级
        breadcrumb['cat3'] = category
        cat2 = category.parent
        breadcrumb['cat2'] = cat2
        breadcrumb['cat1'] = cat2.parent
    else:
        # 当前类别为二级
        breadcrumb['cat2'] = category
        breadcrumb['cat1'] = category.parent

    return breadcrumb

views.py

from goods.models import GoodsCategory, SKU
from django import http
from contents.utils import get_categories
from goods.utils import get_breadcrumb

class ListView(View):
    """商品列表页"""

    def get(self, request, category_id, page_num):
        """提供商品列表页"""
        # 判断category_id是否正确
        try:
            category = models.GoodsCategory.objects.get(id=category_id)
        except models.GoodsCategory.DoesNotExist:
            return http.HttpResponseNotFound('GoodsCategory does not exist')

        # 查询商品频道分类
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(category)

        # 渲染页面
        context = {
            'categories':categories,
            'breadcrumb':breadcrumb
        }
        return render(request, 'list.html', context)

4.2.2. 渲染列表页面包屑导航数据

list.html

<div class="breadcrumb">
    <a href="{{ breadcrumb.cat1.url }}">{{ breadcrumb.cat1.name }}</a>
    <span>></span>
    <a href="javascript:;">{{ breadcrumb.cat2.name }}</a>
    <span>></span>
    <a href="javascript:;">{{ breadcrumb.cat3.name }}</a>
</div>

4.3 列表页分页和排序

# 按照商品创建时间排序
http://www.meiduo.site:8000/list/115/1/?sort=default
# 按照商品价格由低到高排序
http://www.meiduo.site:8000/list/115/1/?sort=price
# 按照商品销量由高到低排序
http://www.meiduo.site:8000/list/115/1/?sort=hot

4.3.1. 查询列表页分页和排序数据

from django.core.paginator import Paginator, EmptyPage


class ListView(View):
    """商品列表页"""

    def get(self, request, category_id, page_num):
        """提供商品列表页"""
        # 判断category_id是否正确
        try:
            category = models.GoodsCategory.objects.get(id=category_id)
        except models.GoodsCategory.DoesNotExist:
            return http.HttpResponseNotFound('GoodsCategory does not exist')
        # 接收sort参数:如果用户不传,就是默认的排序规则
        sort = request.GET.get('sort', 'default')

        # 查询商品频道分类
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(category)

        # 按照排序规则查询该分类商品SKU信息
        if sort == 'price':
            # 按照价格由低到高
            sort_field = 'price'
        elif sort == 'hot':
            # 按照销量由高到低
            sort_field = '-sales'
        else:
            # 'price'和'sales'以外的所有排序方式都归为'default'
            sort = 'default'
            sort_field = 'create_time'
        skus = models.SKU.objects.filter(category=category, is_launched=True).order_by(sort_field)

        # 创建分页器:每页N条记录
        paginator = Paginator(skus, constants.GOODS_LIST_LIMIT)
        # 获取每页商品数据
        try:
            page_skus = paginator.page(page_num)
        except EmptyPage:
            # 如果page_num不正确,默认给用户404
            return http.HttpResponseNotFound('empty page')
        # 获取列表页总页数
        total_page = paginator.num_pages

        # 渲染页面
        context = {
            'categories': categories,   # 频道分类
            'breadcrumb': breadcrumb,   # 面包屑导航
            'sort': sort,               # 排序字段
            'category': category,       # 第三级分类
            'page_skus': page_skus,     # 分页后数据
            'total_page': total_page,   # 总页数
            'page_num': page_num,       # 当前页码
        }
        return render(request, 'list.html', context)

4.3.2. 渲染列表页分页和排序数据

1.渲染分页和排序数据

<div class="r_wrap fr clearfix">
    <div class="sort_bar">
        <a href="{{ url('goods:list', args=(category.id, page_num)) }}?sort=default" {% if sort == 'default' %}class="active"{% endif %}>默认</a>
        <a href="{{ url('goods:list', args=(category.id, page_num)) }}?sort=price" {% if sort == 'price' %}class="active"{% endif %}>价格</a>
        <a href="{{ url('goods:list', args=(category.id, page_num)) }}?sort=hot" {% if sort == 'hot' %}class="active"{% endif %}>人气</a>
    </div>
    <ul class="goods_type_list clearfix">
        {% for sku in page_skus %}
        <li>
        <a href="detail.html"><img src="{{ sku.default_image.url }}"></a>
        <h4><a href="detail.html">{{ sku.name }}</a></h4>
        <div class="operate">
            <span class="price">¥{{ sku.price }}</span>
            <span class="unit">台</span>
            <a href="#" class="add_goods" title="加入购物车"></a>
        </div>
        </li>
        {% endfor %}
    </ul>
</div>

2.列表页分页器

准备分页器标签

<div class="r_wrap fr clearfix">
    ......
    <div class="pagenation">
        <div id="pagination" class="page"></div>
    </div>
</div>

# 导入样式时放在最前面导入
<link rel="stylesheet" type="text/css" href="{{ static('css/jquery.pagination.css') }}">

准备分页器交互? 【放在最下方】

<script type="text/javascript" src="{{ static('js/jquery.pagination.min.js') }}"></script>
<script type="text/javascript">
    $(function () {
        $('#pagination').pagination({
            currentPage: {{ page_num }},
            totalPage: {{ total_page }},
            callback:function (current) {
                {#location.href = '/list/115/1/?sort=default';#}
                location.href = '/list/{{ category.id }}/' + current + '/?sort={{ sort }}';
            }
        })
    });
</script>

4.4 列表页热销排行

【正在上架的,当前类别分类】【不用登录也会看到】

根据路径参数category_id查询出该类型商品销量前二的商品。

使用Ajax实现局部刷新的效果。

4.4.1. 查询列表页热销排行数据

1.请求方式

选项方案
请求方法GET
请求地址/hot/(?P<category_id>\d+)/
#  热销排行
    url(r'^hot/(?P<category_id>\d+)/$', views.HotGoodsView.as_view()),

2.请求参数:路径参数

参数名类型是否必传说明
category_idstring商品分类ID,第三级分类

3.响应结果:JSON

字段说明
code状态码
errmsg错误信息
hot_skus[ ]热销SKU列表
idSKU编号
default_image_url商品默认图片
name商品名称
price商品价格
{
    "code":"0",
    "errmsg":"OK",
    "hot_skus":[
        {
            "id":6,
            "default_image_url":"http://image.meiduo.site:8888/group1/M00/00/02/CtM3BVrRbI2ARekNAAFZsBqChgk3141998",
            "name":"Apple iPhone 8 Plus (A1864) 256GB 深空灰色 移动联通电信4G手机",
            "price":"7988.00"
        },
        {
            "id":14,
            "default_image_url":"http://image.meiduo.site:8888/group1/M00/00/02/CtM3BVrRdMSAaDUtAAVslh9vkK04466364",
            "name":"华为 HUAWEI P10 Plus 6GB+128GB 玫瑰金 移动联通电信4G手机 双卡双待",
            "price":"3788.00"
        }
    ]
}

4.接口定义和实现

from meiduo_mall.utils.response_code import RETCODE


# Create your views here.
class HotGoodsView(View):
    """商品热销排行"""

    def get(self, request, category_id):
        """提供商品热销排行JSON数据"""
        # 根据销量倒序
        skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by('-sales')[:2]

        # 序列化
        hot_skus = []
        for sku in skus:
            hot_skus.append({
                'id': sku.id,
                'default_image_url': sku.default_image.url,
                'name': sku.name,
                'price': sku.price
            })

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_skus': hot_skus})

4.4.2. 渲染列表页热销排行数据

1.模板数据category_id传递到Vue.js

<script type="text/javascript">
    let category_id = "{{ category.id }}";
</script>
data: {
    category_id: category_id,
},

2.Ajax请求商品热销排行JSON数据

get_hot_skus(){
    if (this.category_id) {
        let url = '/hot/'+ this.category_id +'/';
        axios.get(url, {
            responseType: 'json'
        })
            .then(response => {
                this.hot_skus = response.data.hot_skus;
                for(let i=0; i<this.hot_skus.length; i++){
                    this.hot_skus[i].url = '/detail/' + this.hot_skus[i].id + '/';
                }
            })
            .catch(error => {
                console.log(error.response);
            })
    }
},

3.渲染商品热销排行界面

<div class="new_goods" v-cloak>
    <h3>热销排行</h3>
    <ul>
        <li v-for="sku in hot_skus">
            <a :href="sku.url"><img :src="sku.default_image_url"></a>
            <h4><a :href="sku.url">[[ sku.name ]]</a></h4>
            <div class="price">¥[[ sku.price ]]</div>
        </li>
    </ul>
</div>

上面代码写好后,运行可能会报下面的错误:

?解决办法:

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-07-10 11:32:56  更:2021-07-10 11:33:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/22 10:31:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码