商品列表页
商品列表面分析:
从页面观察需要做的功能有:
1,页面中有商品分类,之前已做过,可封装调用
2. 面包屑 也称导航条
3. 热销排行- 由于是时时变化, 一般会存到redis中再进行查询
4. 排序(默认、价格、人气)
5. 根据分类查询展示具体的商品–如三级分类查询出手机
6. 分页
商品列表页组成结构分析
1.商品频道分类
• 已经提前封装在contents.utils.py文件中,直接调用即可。
2.面包屑导航
• 可以使用三级分类ID,查询出该类型商品的三级分类数据。
3.排序和分页
• 无论如何排序和分页,商品的分类不能变。
• 排序时需要知道当前排序方式。
• 分页时需要知道当前分页的页码,且每页五条商品记录。
4.热销排行
• 热销排行中的商品分类要和排序、分页的商品分类一致。
• 热销排行是查询出指定分类商品销量前二的商品。
• 热销排行使用Ajax实现局部刷新的效果。
商品列表页接口设计和定义
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
# 用户随意传排序
http://www.meiduo.site:8000/list/115/1/?sort=ellen
2.请求参数:路径参数 和 查询参数
参数名 类型 是否必传 说明
category_id string 是 商品分类ID,第三级分类
page_num string 是 当前页码
sort string 否 排序方式
3.响应结果:HTML
list.html
4.接口定义
class GoodsListView(View):
"""商品列表页"""
def get(self, request, category_id, page_num):
"""提供商品列表页"""
return render(request, 'list.html')
将goods/view.py 中面包屑(导航条)封装到utils.py中调用
调用contens/utils.py 中get_categories()商品列表页到goods/view.py
# 查询商品分类
categories = get_categories()
# 查询面包屑
breadcrumb = get_breadcrumb(category)
goods/utils.py
# @Time:2021/3/24 14:52
# @Author:Ellen
# @File:utils.py
from .models import GoodsCategory
def get_breadcrumb(category):
# 查询面包屑
# category_id
# 要考虑传了二级或一级情况
# 一级:返回一级 breadcrumb {'cat1':'' }
# 二级:返回二级 breadcrumb {'cat1':'', 'cat2':'',}
# 三级:返回三级 breadcrumb {'cat1':'', 'cat2':'','cat3': ''}
breadcrumb = {
'cat1': '',
'cat2': '',
'cat3': '',
}
if category.parent == None:
# 一级
breadcrumb['cat1'] = category
elif GoodsCategory.objects.filter(parent_id=category.id).count() == 0:
# 三级
cat2 = category.parent
breadcrumb['cat1'] = cat2.parent
breadcrumb['cat2'] = cat2
breadcrumb['cat3'] = category
else:
# 二级
breadcrumb['cat1'] = category.parent
breadcrumb['cat2'] = category
# 这种情况默认只能传三级category_id 要考虑传了二级或一级情况
# breadcrumb = {
# 'cat1': category.parent.parent,
# 'cat2': category.parent,
# 'cat3': category,
# }
return breadcrumb
添加页码分页排序
goods/view.py
# 先规定每页多少字,然后得出一共多少页
from django.core.paginator import Paginator
....
# 分页和排序
skus = SKU.objects.filter(is_launched=True, category_id=category.id).order_by(sort_field)
# print(skus)
# Paginator('要分页的数据', '每句分页的条数')
paginator = Paginator(skus, 5) # 把sku进行分页,每页5条数据
try:
# 获取用户当前要看的那页数据
page_skus = paginator.page(page_num)
except Exception as e:
return http.HttpResponseNotFound('Empty page')
# print(page_skus)
#总页数
total_page = paginator.num_pages
# for sku in page_skus:
# print(sku.default_image.url)
context = {
"categories": categories,
"breadcrumb": breadcrumb,
"page_skus": page_skus,
"total_page": total_page,
"sort": sort,
"category_id": category_id,
"page_num": page_num,
}
return render(request, 'list.html', context=context)
goods/ list.html
<link rel="stylesheet" type="text/css" href="{% static 'css/jquery.pagination.css' %}">
<div class="r_wrap fr clearfix">
<div class="sort_bar">
<a href="{% url 'goods:list' category_id page_num %}?sort=default" {
% if sort == 'default' %}class="active"
{
% endif %}>默认</a>
<a href="{% url 'goods:list' category_id page_num %}?sort=price" {
% if sort == 'price' %}class="active"
{
% endif %}>价格</a>
<a href="{% url 'goods:list' category_id page_num %}?sort=hot" {
% if sort == 'hot' %}class="active"
{
% endif %}>人气</a>
</div>
<script type="text/javascript">
let category_id = "";
</script>
<script type="text/javascript" src="{% static 'js/common.js' %}"></script>
<script type="text/javascript" src="{% static 'js/list.js' %}"></script>
<script type="text/javascript" src="{% static 'js/jquery.pagination.min.js' %}"></script>
<script>
$(function () {
$('#pagination').pagination({
currentPage: {
{
page_num }},
totalPage: {
{
total_page }},
callback:function (current) {
location.href = '/list/{
{ category_id }}/' + current + '/?sort={
{ sort }}';
}
})
});
</script>
<script type="text/javascript" src="{% static 'js/jquery.pagination.min.js' %}"></script>
热销排行榜
goods/view.py
class HotGoodsView(View):
"""热销排行 """
def get(self, request, category_id):
# 查询指定的分类(category_id)必须是上架商品
skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by('-sales')[:2]
# print(skus)
# 模型转字典列表
hot_skus = []
for sku in skus:
sku_dict = {
"id": sku.id,
"name": sku.name,
"price": sku.price,
"default_image_url": sku.default_image.url
}
hot_skus.append(sku_dict)
# print(hot_skus)
return http.JsonResponse({
"code": RETCODE.OK, "errmsg": 'OK', "hot_skus": hot_skus})
list.html
<h3>热销排行</h3>
<ul>
<li v-for="sku in hot_skus">
<a href="detail.html"><img :src="sku.default_image_url"></a>
<h4><a href="detail.html">[[ sku.name ]]</a></h4>
<div class="price">¥[[ sku.price ]]</div>
</li>
</ul>