当用户访问网址/list.html?cat=xxx时, 会进入商品列表页。网址中的cat参数是用于过滤商品数据的第三季商品类别,也就是在商品列表中会根据cat参数筛选商品数据用于展示。
#meiduo_mall/apps/goods/utils.py
# -*-coding:utf-8-*-
from collections import OrderedDict
from goods.models import GoodsChannel
def get_categories():
"""
获取商品分类菜单
:return:
"""
# 商品频道及分类菜单
# 使用有序字典保存类别的顺序
# categories = {
# 1: { # 组1
# 'channels': [{'id':, 'name':, 'url':},{}, {}...],
# 'sub_cats': [{'id':, 'name':, 'sub_cats':[{},{}]}, {}, {}, ..]
# },
# 2: { # 组2
#
# }
# }
categories = OrderedDict()
channels = GoodsChannel.objects.order_by('group_id', 'sequence')
for channel in channels:
group_id = channel.group_id # 当前组
if group_id not in categories:
categories[group_id] = {'channels': [], 'sub_cats': []}
cat1 = channel.category # 当前频道的类别
# 追加当前频道
categories[group_id]['channels'].append({
'id': cat1.id,
'name': cat1.name,
'url': channel.url
})
# 构建当前类别的子类别
for cat2 in cat1.goodscategory_set.all():
cat2.sub_cats = []
for cat3 in cat2.goodscategory_set.all():
cat2.sub_cats.append(cat3)
categories[group_id]['sub_cats'].append(cat2)
return categories
# celery_tasks/html.tasks.py
# -*-coding:utf-8-*-
import os
from celery.contrib.pytest import celery_app
from django.conf import settings
from django.template import loader
from goods.utils import get_categories
@ celery_app.tasks(name='generate_static_list_search_html')
def generate_static_list_search_html():
"""
生成静态的商品列表页和搜索结果页html文件
:return:
"""
# 商品分类菜单
categories = get_categories()
# 渲染模板,生成静态文件
context = {
'categories':categories
}
template = loader.get_template('list.html')
html_text = template.render(context)
file_path = os.path.join(settings.GENERATED_STATIC_HTML_FILES_DIR, 'list.html')
with open(file_path, 'w') as f:
f.write(html_text)
# meiduo_mall/apps/goods/admin.py
from django.contrib import admin
# Register your models here.
from goods.models import GoodsCategory, Brand, Goods, SKU, GoodsChannel, GoodsSpecification, SpecificationOption, \
SKUSpecification, SKUImage
class GoodsCategoryAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.save()
from celery_tasks.html.tasks import generate_static_list_search_html
generate_static_list_search_html.delay()
def delete_model(self, request, obj):
obj.delete()
from celery_tasks.html.tasks import generate_static_list_search_html
generate_static_list_search_html.delay()
admin.site.register(GoodsCategory, GoodsCategoryAdmin)
admin.site.register(GoodsChannel)
admin.site.register(Goods)
admin.site.register(Brand)
admin.site.register(GoodsSpecification)
admin.site.register(SpecificationOption)
admin.site.register(SKU)
admin.site.register(SKUSpecification)
admin.site.register(SKUImage)
请求方式: GET /categories/(?P
请求参数: 路径传参, 查询字符串
参数名 | 类型 | 是否必须 | 说明 |
---|---|---|---|
category_id | int | 是 | 商品分类id(第三级) |
page | int | 是 | 请求页数 |
page_size | int | 否 | 每页数量 |
ordering | str | 是 | 排序关键字(‘create_time’, ‘price’, ‘sales’) |
返回数据: JSON
{
"count": 14,
"next": "http://api.meiduo.site:8000/categories/115/skus/?page=2",
"previous": null,
"results": [
{
"id": 3,
"name": "Apple iPhone 8 Plus (A1864) 64GB 金色 移动联通电信4G手机",
"price": "6499.00",
"default_image_url": "http://image.meiduo.site:8888/group1/M00/00/02/CtM3BVrRZCqAUxp9AAFti6upbx41220032",
"comments": 0
},
{
"id": 4,
"name": "Apple iPhone 8 Plus (A1864) 256GB 金色 移动联通电信4G手机",
"price": "7988.00",
"default_image_url": "http://image.meiduo.site:8888/group1/M00/00/02/CtM3BVrRZa6ANO_sAAFti6upbx40753757",
"comments": 0
}
]
}
返回值 | 类型 | 是否必须 | 说明 |
---|---|---|---|
count | int | 是 | |
next | url | 是 | 下一页的链接地址 |
previous | url | 是 | 上一页的链接地址 |
results | sku[] | 是 | 商品sku数据列表 |
id | int | 否 | 商品sku 编号 |
name | str | 否 | 商品名称 |
price | decimal | 否 | 单价 |
default_image_url | str | 否 | 默认图片 |
comments | int | 否 | 评论量 |
在meiduo_mall/utils中创建pagination.py文件,并在其中创建分页配置类:
# meiduo_mall/utils/pagination.py
# -*-coding:utf-8-*-
from rest_framework.pagination import PageNumberPagination
class StandardResultsSetPagination(PageNumberPagination):
page_size = 2
page_size_query_param = 'page_size'
max_page_size = 20
在配置文件中设置REST framework分页使用的分页类:
# meiduo_mall/settings/dev.py
REST_FRAMEWORK = {
...
# 分页
'DEFAULT_PAGINATION_CLASS': 'meiduo_mall.utils.pagination.StandardResultsSetPagination',
}
定义序列化器
# meiduo_mall/apps/goods/serializers.py
# -*-coding:utf-8-*-
from rest_framework import serializers
from goods.models import SKU
class CategoriesListSerializer(serializers.ModelSerializer):
"""列表页序列化器"""
# create_time = serializers.DateField(read_only=True)
# update_time = serializers.DateField(read_only=True)
class Meta:
model = SKU
fields = "__all__"
在goods/views.py中实现视图:
# meiduo_mall/apps/goods/views.py
from django.shortcuts import render
# Create your views here.
from rest_framework.filters import OrderingFilter
from rest_framework.generics import ListAPIView
from goods.models import SKU
from goods.serializers import CategoriesListSerializer
class SKUListView(ListAPIView):
"""
sku列表数据
"""
serializer_class = CategoriesListSerializer
# 分页与排序
filter_backends = (OrderingFilter,)
ordering_fields = ('create_time', 'price', 'sales')
def get_queryset(self):
"""
获取查询集
:return:
"""
return SKU.objects.filter(category_id=self.kwargs["pk"])
说明:
REST framework提供了对于排序的支持,使用REST framework提供的OrderingFilter过滤器后端即可。
OrderingFilter过滤器要使用ordering_fields 属性来指明可以进行排序的字段有哪些。
注册路由:
# meiduo_mall/apps/goods/urls.py
# -*-coding:utf-8-*-
from django.conf.urls import url
from goods import views
urlpatterns = [
url(r"^categories/(?P\d+)/skus/$" ,views.SKUListView.as_view()),
]