def get(self, request, category_id, page): try: category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return render(request, '404.html') breadcrumb = get_breadcrumb(category) sort = request.GET.get('sort') if sort == 'default': order_field = 'create_time' elif sort == 'hot': order_field = 'sales' else: order_field = '-price' data = SKU.objects.filter(category=category) from django.core.paginator import Paginator paginator = Paginator(object_list=data, per_page=5) page_data = paginator.page(page) total_page = paginator.num_pages context = { 'breadcrumb': breadcrumb, # 面包屑导航 'sort': sort, # 排序字段 'category': category, # 第三级分类 'page_skus': page_data, # 分页后数据 'total_page': total_page, # 总页数 'page_num': page, # 当前页码 } return render(request, 'list.html', context=context)
def get_detail_html(sku_id): """ 生成静态商品详情页面 :param sku_id: 商品sku id """ # 获取当前sku的信息 sku = models.SKU.objects.get(id=sku_id) # 查询商品频道分类 categories = get_categories() # 查询面包屑导航 breadcrumb = get_breadcrumb(sku.category) # 构建当前商品的规格键 sku_specs = sku.specs.order_by('spec_id') sku_key = [] for spec in sku_specs: sku_key.append(spec.option.id) # 获取当前商品的所有SKU skus = sku.spu.sku_set.all() # 构建不同规格参数(选项)的sku字典 spec_sku_map = {} for s in skus: # 获取sku的规格参数 s_specs = s.specs.order_by('spec_id') # 用于形成规格参数-sku字典的键 key = [] for spec in s_specs: key.append(spec.option.id) # 向规格参数-sku字典添加记录 spec_sku_map[tuple(key)] = s.id # 获取当前商品的规格信息 goods_specs = sku.spu.specs.order_by('id') # 若当前sku的规格信息不完整,则不再继续 if len(sku_key) < len(goods_specs): return for index, spec in enumerate(goods_specs): # 复制当前sku的规格键 key = sku_key[:] # 该规格的选项 spec_options = spec.options.all() for option in spec_options: # 在规格参数sku字典中查找符合当前规格的sku key[index] = option.id option.sku_id = spec_sku_map.get(tuple(key)) spec.spec_options = spec_options # 上下文 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, 'specs': goods_specs, } template = loader.get_template('detail.html') html_text = template.render(context) file_path = os.path.join(settings.STATICFILES_DIRS[0], 'detail/' + str(sku_id) + '.html') with open(file_path, 'w') as f: f.write(html_text)
def get(self, request, sku_id): # 查看当前sku的信息 try: sku = SKU.objects.get(id=sku_id) except SKU.DoesNotExist: return render(request, '404.html') # 调用商品频道三级分类 categories = get_categories() # 掉用面包屑组件 breadcrumb = get_breadcrumb(sku.category) # 构建当前商品的规格键 sku_specs = sku.specs.order_by('spec_id') sku_key = [] for spec in sku_specs: sku_key.append(spec.option.id) # 获取当前商品的所有SKU skus = sku.spu.sku_set.all() # 构建不同的规格参数(选项)的sku字典 spec_sku_map = {} for s in skus: # 获取sku的规格参数 s_specs = s.specs.order_by('spec_id') # 用于形成规格参数-sku字典的键 key = [] for spec in s_specs: key.append(spec.option.id) # 向规格参数-sku字典添加记录 spec_sku_map[tuple(key)] = s.id # 获取当前商品的规格信息 goods_specs = sku.spu.specs.order_by('id') # 若当前sku的规格信息不完整,则不再继续 if len(sku_key) < len(goods_specs): return for index, spec in enumerate(goods_specs): # 复制当前的sku的规格键 key = sku_key[:] # 该规格的选项 spec_options = spec.options.all() for option in spec_options: # 在规格参数sku字典中查找符合当前规格的sku key[index] = option.id option.sku_id = spec_sku_map.get(tuple(key)) spec.spec_options = spec_options # 渲染页面 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, 'specs': goods_specs, } return render(request, 'detail.html', context)
def get(self, request, sku_id): try: sku = SKU.objects.get(id=sku_id) except SKU.DoesNotExist: return render(request, '404.html') # 查询商品频道分类 categories = get_categories() # 查询面包屑导航 breadcrumb = get_breadcrumb(sku.category) # 查询当前sku所对应的spu spu = sku.spu # 获取当前sku所对应的三级分类 category = sku.category """1.准备当前商品的规格选项列表 [8, 11]""" # 获取出当前正显示的sku商品的规格选项id列表 current_sku_spec_qs = sku.specs.order_by('spec_id') current_sku_option_ids = [] # [8, 11] for current_sku_spec in current_sku_spec_qs: current_sku_option_ids.append(current_sku_spec.option_id) """2.构造规格选择仓库 {(8, 11): 3, (8, 12): 4, (9, 11): 5, (9, 12): 6, (10, 11): 7, (10, 12): 8} """ # 构造规格选择仓库 temp_sku_qs = spu.sku_set.all() # 获取当前spu下的所有sku # 选项仓库大字典 spec_sku_map = {} # {(8, 11): 3, (8, 12): 4, (9, 11): 5, (9, 12): 6, (10, 11): 7, (10, 12): 8} for temp_sku in temp_sku_qs: # 查询每一个sku的规格数据 temp_spec_qs = temp_sku.specs.order_by('spec_id') temp_sku_option_ids = [] # 用来包装每个sku的选项值 for temp_spec in temp_spec_qs: temp_sku_option_ids.append(temp_spec.option_id) spec_sku_map[tuple(temp_sku_option_ids)] = temp_sku.id """3.组合 并找到sku_id 绑定""" spu_spec_qs = spu.specs.order_by('id') # 获取当前spu中的所有规格 for index, spec in enumerate(spu_spec_qs): # 遍历当前所有的规格 spec_option_qs = spec.options.all() # 获取当前规格中的所有选项 temp_option_ids = current_sku_option_ids[:] # 复制一个新的当前显示商品的规格选项列表 for option in spec_option_qs: # 遍历当前规格下的所有选项 temp_option_ids[index] = option.id # [8, 12] option.sku_id = spec_sku_map.get(tuple(temp_option_ids)) # 给每个选项对象绑定下他sku_id属性 spec.spec_options = spec_option_qs # 把规格下的所有选项绑定到规格对象的spec_options属性上 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, 'spu': spu, 'category': category, 'spec_qs': spu_spec_qs } return render(request, 'detail.html', context)
def generate_static_sku_detail_html(sku): # 调用商品分类频道 categories = get_categories() # 调用面包屑组件 breadcrumb = get_breadcrumb(sku.category) # 构建当前商品的规格键 sku_specs = sku.specs.order_by('spec_id') sku_key = [] for spec in sku_specs: sku_key.append(spec.option.id) # 获取当前商品的所有SKU skus = sku.spu.sku_set.all() # 构建不同规格参数(选项)的sku字典 spec_sku_map = {} for s in skus: # 获取sku的规格参数 s_specs = s.specs.order_by('spec_id') # 用于形成规格参数-sku字典的键 key = [] for spec in s_specs: key.append(spec.option.id) # 向规格参数-sku字典添加记录 spec_sku_map[tuple(key)] = s.id # 获取当前商品的规格信息 goods_specs = sku.spu.specs.order_by('id') # 若当前sku的规格信息不完整,则不再继续 if len(sku_key) < len(goods_specs): return for index, spec in enumerate(goods_specs): # 复制当前sku的规格键 key = sku_key[:] # 该规格的选项 spec_options = spec.options.all() for option in spec_options: # 在规格参数sku字典中查找符合当前规格的sku key[index] = option.id option.sku_id = spec_sku_map.get(tuple(key)) spec.spec_options = spec_options # 渲染页面 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, 'specs': goods_specs, } # 获取详情页模板 templage = loader.get_template('detail.html') # 渲染成html_text html_text = templage.render(context) # 将html_text写入指定文件 file_path = os.path.join(settings.STATICFILES_DIRS[0], 'detail/' + str(sku.id) + '.html') with open(file_path, 'w', encoding='utf-8') as file: file.write(html_text)
def get(self, request, sku_id): """ 1.根据sku_id,进行查询 2.获取面包屑 3.获取分类数据 """ # 1.根据sku_id,进行查询 try: sku = SKU.objects.get(pk=sku_id) except Exception as e: return render(request, '404.html') # 2.获取面包屑 breadcrumb = get_breadcrumb(sku.category) # 3.获取分类数据 categories = get_categories() # 构建当前商品的规格键 sku_specs = sku.specs.order_by('spec_id') sku_key = [] for spec in sku_specs: sku_key.append(spec.option.id) # 获取当前商品的所有SKU skus = sku.spu.sku_set.all() # 构建不同规格参数(选项)的sku字典 spec_sku_map = {} for s in skus: # 获取sku的规格参数 s_specs = s.specs.order_by('spec_id') # 用于形成规格参数-sku字典的键 key = [] for spec in s_specs: key.append(spec.option.id) # 向规格参数-sku字典添加记录 spec_sku_map[tuple(key)] = s.id # 获取当前商品的规格信息 goods_specs = sku.spu.specs.order_by('id') # 若当前sku的规格信息不完整,则不再继续 if len(sku_key) < len(goods_specs): return for index, spec in enumerate(goods_specs): # 复制当前sku的规格键 key = sku_key[:] # 该规格的选项 spec_options = spec.options.all() for option in spec_options: # 在规格参数sku字典中查找符合当前规格的sku key[index] = option.id option.sku_id = spec_sku_map.get(tuple(key)) spec.spec_options = spec_options context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, 'specs': goods_specs } return render(request, 'detail.html', context=context)
def get(self, request, category_id, page_num): # 判断有没有三级分类数据 try: category = GoodsCategory.objects.get(id=category_id) except Exception as e: logger.error(e) return http.HttpResponseNotFound('GoodsCategory does not exist') # 调用商品频道分类分数 categories = get_categories() # 调用面包屑导航 breadcrumb = get_breadcrumb(category) # 按照排序规则查询该分类商品SKU信息 # 获取用户的查询方式 sort = request.GET.get('sort', 'default') # 判断 if sort == 'price': sort_field = 'price' elif sort == 'hot': sort_field = '-sales' else: sort_field = 'create_time' # SKU信息排序 skus = SKU.objects.filter(category=category, is_launched=True).order_by(sort_field) # 分页 from django.core.paginator import Paginator # 实例化分页器 提供内容和分页的数 pagenator = Paginator(skus, constants.GOODS_LIST_LIMIT) # 获取总页数 total_page = pagenator.num_pages # 获取每页的数据 try: page_skus = pagenator.page(page_num) except Exception as e: logger.error(e) return http.HttpResponseNotFound('empty page') # 渲染页面 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)
def get(self, request, category_id): """ 提供商品列表数据和面包屑导航数据 :param category_id: 商品第三级分类 :return: JSON """ # 接收参数 page_num = request.GET.get('page') # 当前用户想看的页码 page_size = request.GET.get('page_size') # 该页中想看的记录的个数 ordering = request.GET.get('ordering') # 排序字段 # 校验参数 # 校验category_id是否存在 try: category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return http.JsonResponse({'code': 400, 'errmsg': 'category_id不存在'}) # 提示:page_num,page_size,ordering不需要单独校验的,因为在排序和分页时,校验的 # 实现核心逻辑:排序和分页、面包屑导航 # 我们查询指定分类下,未被下架的SKU信息,再排序 skus = SKU.objects.filter(category=category, is_launched=True).order_by(ordering) # 分页查询 # 创建分页器对象:分页器对象 = Paginator(要分页的查询集, 每页记录个数) paginator = Paginator(skus, page_size) # 获取指定页中的模型数据:paginator.page(页码) try: page_skus = paginator.page(page_num) except EmptyPage: return http.JsonResponse({'code': 400, 'errmsg': '页码错误'}) # 获取分页后的总页数 total_pages = paginator.num_pages # 将分页后的查询集转字典列表 list = [] for sku in page_skus: list.append({ "id": sku.id, "default_image_url": sku.default_image.url, "name": sku.name, "price": sku.price }) # 面包屑导航 breadcrumb = get_breadcrumb(category) # 响应结果 return http.JsonResponse({ 'code': 0, 'errmsg': 'OK', 'breadcrumb': breadcrumb, # 面包屑导航 'list': list, # 排序后的分页数据,不能是模型数据,因为JsonResponse不识别 'count': total_pages # 分页后的总页数 })
def get(self, request, category_id, page_num): ''' 商品三级列表 :param request: :param category_id: :param page_num: :return: ''' """提供商品列表页""" # 判断category_id是否正确 try: category = models.GoodsCategory.objects.get(id=category_id) except models.GoodsCategory.DoesNotExist: return HttpResponseNotFound('GoodsCategory does not exist') # 1.0 三级列表 categories = get_categories() # 2.0 面包屑 # 接收sort参数:如果用户不传,就是默认的排序规则 sort = request.GET.get('sort', 'default') # 默认 if sort == 'price': # 升序 价格从低到高 sort_field = 'price' elif sort == 'hot': # 降序 热度从搞到低 sort_field = '-sales' else: # 其余的都是默认 sort_field = 'create_time' skus = 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 HttpResponseNotFound('empty page') # 获取列表页总页数 total_page = paginator.num_pages breadcrumb = get_breadcrumb(category) 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)
def get(self, request, sku_id): # 1.根据sku_id获取当前sku的信息 try: sku = SKU.objects.get(id=sku_id) except Exception as e: # todo 如果搜索的商品不存在,直接跳转商品不存在的404页面 return render(request, '404.html') # 2.查询商品频道分类 categories = get_categories() # 3.查询面包屑导航 breadcrumb = get_breadcrumb(sku.category) """多对多的信息""" # 4.构建当前商品的规格键 sku_specs = sku.specs.order_by('spec_id') sku_key = [] for spec in sku_specs: sku_key.append(spec.option.id) # 获取当前商品的所有SKU skus = sku.spu.sku_set.all() # 构建不同规格参数(选项)的sku字典 spec_sku_map = {} for s in skus: # 获取sku的规格参数 s_specs = s.specs.order_by('spec_id') # 用于形成规格参数-sku字典的键 key = [] for spec in s_specs: key.append(spec.option.id) # 向规格参数-sku字典添加记录 spec_sku_map[tuple(key)] = s.id # 获取当前商品的规格信息 goods_specs = sku.spu.specs.order_by('id') # 若当前sku的规格信息不完整,则不再继续 if len(sku_key) < len(goods_specs): return for index, spec in enumerate(goods_specs): # 复制当前sku的规格键 key = sku_key[:] # 该规格的选项 spec_options = spec.options.all() for option in spec_options: # 在规格参数sku字典中查找符合当前规格的sku key[index] = option.id option.sku_id = spec_sku_map.get(tuple(key)) spec.spec_options = spec_options # 5.组织渲染页面的数据 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, 'specs': goods_specs, } return render(request, 'detail.html', context)
def get(self, request, category_id, page_num): # 获取三级分类的对象 try: category = GoodsCategory.objects.get(id=category_id) except Exception as e: return HttpResponseNotFound('商品分类不存在') # 1.商品分类数据 from apps.contents.utils import get_categories categories = get_categories() # 2.面包屑组件数据 from apps.goods.utils import get_breadcrumb breadcrumb = get_breadcrumb(category) # 3. 排序 # 3.1 获取sort 里面的参数值 查询参数 sort = request.GET.get('sort', 'default') # 3.2 判断 排序的字段值 sort 模型对象 if sort == 'price': sort_field = 'price' elif sort == 'hot': sort_field = '-sales' else: # 默认都是 创建时间排序 sort_field = 'create_time' # 3.3 根据排序规则 获取category_id 对应的所有 上架的商品 skus = SKU.objects.filter(category=category, is_launched=True).order_by(sort_field) # 4. 分页--django提供了分页器 # 4.1 实例化 分页器(分页的数据,每页显示的个数)==>返回每页显示的数据skus from django.core.paginator import Paginator paginator = Paginator(skus, 5) # 4.2 告诉分页器 当前显示的页数 try: page_skus = paginator.page(page_num) except Exception as e: return HttpResponseNotFound('当前页数超出范围了!') # 4.3 获取总页数 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)
def get(self, request, category_id, page_num): # 判断category_id是否正确 try: category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return http.HttpResponseNotFound('GoodsCategory does not exist') # 调用商品频道三级联动 categories = get_categories() # 调用面包屑导航 breadcrumb = get_breadcrumb(category) # 排序 # 1 接收参数 sort = request.GET.get('sort', 'default') # 2 校验参数 if sort == 'price': sort_filed = 'price' elif sort == 'hot': sort_filed = '-sales' else: sort_filed = 'create_time' # 3 对商品信息进行排序 skus = SKU.objects.filter(category=category, is_launched=True).order_by(sort_filed) # 分页 # 1 创建分页器对象 paginator = Paginator(skus, constants.GOODS_LIST_LIMIT) # 2 获取每页的数据 try: page_skus = paginator.page(page_num) except EmptyPage: # 如果page_num不正确,默认给用户404 return http.HttpResponseNotFound('empty page') # 3 获取总页数 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)
def get(self, request, category_id, page_num): """提供商品列表页""" # 判断category_id是否正确 try: category = GoodsCategory.objects.get(pk=category_id) except GoodsCategory.DoesNotExist: return http.HttpResponseBadRequest('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 = SKU.objects.filter(category=category, is_launched=True).order_by(sort_field) # 创建分页器:每页N条记录 paginator = Paginator(skus, 5) # 获取每页商品数据 try: page_skus = paginator.page(page_num) except Exception as e: logger.error(e) # 如果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=context)
def get(self, request, category_id, page_num): """ 1.判断category_id 2.获取分类数据 3.获取面包屑数据 4.组织排序字段 5.分页 6.组织数据 7.返回相应 """ # 1.判断category_id try: category = GoodsCategory.objects.get(pk=category_id) except Exception as e: return http.HttpResponseNotFound('分类数据错误') # 2.获取分类数据 categories = get_categories() # 3.获取面包屑数据 breadcrumb = get_breadcrumb(category) # 4.组织排序字段 sort = request.GET.get('sort') order_field = '' if sort == 'price': order_field = 'price' elif sort == 'hot': order_field = '-sales' else: sort = 'default' order_field = 'create_time' skus = SKU.objects.filter(category=category, is_launched=True).order_by(order_field) # 5.分页 paginator = Paginator(skus, per_page=5) try: page_num = int(page_num) page_skus = paginator.page(page_num) except Exception as e: return http.HttpResponseNotFound('empty page') #总页数 total_page = paginator.num_pages # 6.组织数据 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sort': sort, # 排序字段 'category': category, # 第三级分类 'page_skus': page_skus, # 分页后数据 'total_page': total_page, # 总页数 'page_num': page_num, # 当前页码 } # 7.返回相应 return render(request, 'list.html', context=context)
def get(self, request, category_id, page_num): """ :param category_id: 三级分类ID :param page_num: 当前页数 """ try: cat3 = GoodsCategory.objects.get(pk=category_id) except: return http.HttpResponseForbidden('商品不存在!') # 1.获取 商品 分类数据 categories = get_categories() # 2.面包屑组件的功能 breadcrumbs = get_breadcrumb(cat3) # 3. 排序 --获取 所有 SKU的值 # 前端传入的 sort 值 和 数据库的 字段 不对应 , 所以需要代码转换 sort = request.GET.get('sort') if sort == "price": order_field = 'price' elif sort == 'hot': order_field = '-sales' else: order_field = 'create_time' # 查询出来的 所有 skus skus = SKU.objects.filter(category=cat3, is_launched=True).order_by(order_field) # 1.导包分页器 from django.core.paginator import Paginator # 2.实例化 paginator = Paginator(skus, 5) # 3.获取 当前页的 skus数据 page_skus = paginator.page(page_num) # 4.获取总个数 total_page = paginator.num_pages context = { 'categories': categories, 'breadcrumbs': breadcrumbs, 'sort': sort, # 排序字段 'category': cat3, # 第三级分类 'page_skus': page_skus, # 分页后数据 'total_page': total_page, # 总页数 'page_num': page_num, # 当前页码 } return render(request, 'list.html', context)
def get(self, request, sku_id): try: sku = SKU.objects.get(id=sku_id) except SKU.DoesNotExist: return render(request, '404.html') categories = get_categories() breadcrumb = get_breadcrumb(sku.category) sku_specs = sku.specs.order_by('spec_id') sku_key = [] for spec in sku_specs: sku_key.append(spec.option.id) skus = sku.spu.sku_set.all() spec_sku_map = {} for s in skus: s_specs = s.specs.order_by('spec_id') key = [] for spec in s_specs: key.append(spec.option.id) spec_sku_map[tuple(key)] = s.id goods_specs = sku.spu.specs.order_by('id') if len(sku_key) < len(goods_specs): return for index, spec in enumerate(goods_specs): key = sku_key[:] spec_options = spec.options.all() for option in spec_options: key[index] = option.id option.sku_id = spec_sku_map.get(tuple(key)) spec.spec_options = spec_options context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, 'specs': goods_specs, } return render(request, 'detail.html', context)
def get(self,request,category_id,page): try: category=GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return render(request,'404.html') # 面包屑 # 因为很多地方,都用到了面包屑,将面包屑,抽取出去 breadcrumb=get_breadcrumb(category) # 尽量不要将表的信息,暴露出去 # 排序字段是使用的查询字符串 ?sort= # default:以上架时间 # hot :热销 销量 # price :价格 sort=request.GET.get('sort') if sort == 'default': order_field='create_time' elif sort == 'hot': order_field='sales' else: order_field='-price' # ① 先根据分类,把所有数据查询出来 data=SKU.objects.filter(category=category).order_by(order_field) # data=SKU.objects.filter(category_id=category_id) # ② 添加排序 # ③ 添加分页 from django.core.paginator import Paginator # 3.1创建分页对象 # per_page : 每页多少条数据 paginator=Paginator(object_list=data,per_page=5) # 3.2获取指定页面的数据 page_data=paginator.page(page) # 3.3获取总页数 total_page=paginator.num_pages context = { 'breadcrumb': breadcrumb, # 面包屑导航 'sort': sort, # 排序字段 'category': category, # 第三级分类 'page_skus': page_data, # 分页后数据 'total_page': total_page, # 总页数 'page_num': page, # 当前页码 } return render(request,'list.html',context=context)
def get(self, request, category_id, page_num): # category_id 三级分类ID # 1.三级分类 调用 contents 封装好的代码 categories = get_categories() # 2.面包屑组件 cat3.parent # 获取cat3对象 cat3 = GoodsCategory.objects.get(id=category_id) bread_crumb = get_breadcrumb(cat3) # 3.排序 按照排序规则查询该分类商品SKU信息 # 3.1 sort == 'price':前端传入参数 hot default 不能直接对接数据库 sort = request.GET.get('sort') if sort == 'price': order_field = 'price' elif sort == 'hot': order_field = '-sales' else: order_field = 'create_time' # 3.2 SKU.objects.filter().order_by() skus = SKU.objects.filter(category=cat3, is_launched=True).order_by(order_field) print(skus) # 4.分页器--paginator from django.core.paginator import Paginator # 4.1 一页显示几个 paginator = Paginator(skus, contants.GOODS_LIST_LIMIT) # 4.2 总页数 all_pages = paginator.num_pages # 4.3 当前页 显示的内容 page_skus = paginator.page(page_num) context = { 'categories': categories, # 频道分类 'breadcrumb': bread_crumb, # 面包屑导航 'sort': sort, # 排序字段 'category': cat3, # 第三级分类 'page_skus': page_skus, # 分页后数据 'total_page': all_pages, # 总页数 'page_num': page_num, # 当前页码 } return render(request, 'list.html', context)
def get(self, request, sku_id): try: sku = models.SKU.objects.get(id=sku_id) except models.SKU.DoesNotExist: return render(request, '404.html') # 查询商品频道分类 categories = get_categories() # 查询面包屑导航 breadcrumb = get_breadcrumb(sku.category) # 渲染页面 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, } return render(request, "detail.html", context)
def get(self, request, category_id, page_num): cat3 = GoodsCategory.objects.get(id=category_id) # * 1. 三级商品分类 调用 contents 封装好的代码 categories = get_categories() # * 2. 面包屑组件 cat3.parent breadcrumb = get_breadcrumb(cat3) # * 3. 排序 order_by sort = request.GET.get('sort') # * 默认 价格 人气=== -create_time price -sales if sort == "price": order_field = "price" elif sort == "hot": order_field = '-sales' else: order_field = "create_time" skus = SKU.objects.filter(category=cat3, is_launched=True).order_by(order_field) # * 4. 分页器 paginator: 一页几个; 每页的内容skus; 总页数 from django.core.paginator import Paginator paginator = Paginator(skus, 5) page_skus = paginator.page(page_num) total_pages = paginator.num_pages # * 5.热销商品 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sort': sort, # 排序字段 'category': cat3, # 第三级分类 'page_skus': page_skus, # 分页后数据 'total_page': total_pages, # 总页数 'page_num': page_num, # 当前页码 } return render(request, 'list.html', context)
def get(self, request, category_id, page_num): try: category = models.GoodsCategory.objects.get(id=category_id) except models.GoodCategory.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_field = 'create_time' skus = models.SKU.objects.filter(category=category, is_launched=True).order_by(sort_field) paginator = Paginator(skus, 5) page_skus = paginator.page(page_num) 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)
def get(self, request, category_id, page): """提供商品列表页""" try: category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return render(request, '404.html') # 1.根据分类,查询所有数据 data = SKU.objects.filter(category=category) # 面包屑导航 将它抽取出去 breadcrumb = get_breadcrumb(category) # 2.添加排序 # default:上架时间 # hot:热销 # price:价格 sort = request.GET.get('sort') if sort == 'defalt': order_filed = 'create_time' elif sort == 'hot': order_filed = 'sales' else: order_filed = '-price' data = SKU.objects.filter(category=category).order_by(order_filed) # 3.添加分页 from django.core.paginator import Paginator # 3.1创建分页对象 paginator = Paginator(object_list=data, per_page=5) # 3.2 获取指定页面数据 page_data = paginator.page(page) total_page = paginator.num_pages # 3.3获取总页数 context = { 'breadcrumb': breadcrumb, # 面包屑导航 'sort': sort, # 排序字段 'category': category, # 第三级分类 'page_skus': page_data, # 分页后数据 'total_page': total_page, # 总页数 'page_num': page, # 当前页码 } return render(request, 'list.html', context=context)
def get(self, request, category_id, page_num): # category_id 三级分类id category = GoodsCategory.objects.get(id=category_id) # 1. 商品分类数据 categories = get_categories() # 2.获取面包屑组件 bread_crumb = get_breadcrumb(category) # 3. 排序判断 default==create_time price=price hot==-sales sort = request.GET.get('sort') order_field = "create_time" if sort == "price": order_field = "price" elif sort == "hot": order_field = "-sales" else: order_field = "create_time" # 获取 所有上架的商品(对应的类)---排序 skus = SKU.objects.filter(category=category, is_launched=True).order_by(order_field) # 每页有几个; 每页显示哪几个 ; 总页数; 当前页数 page_num from django.core.paginator import Paginator paginator = Paginator(skus, 5) page_skus = paginator.page(page_num) total_nums = paginator.num_pages context = { 'categories': categories, 'breadcrumb': bread_crumb, 'category': category, 'sort': sort, # 排序字段 'page_skus': page_skus, # 分页后数据 'total_page': total_nums, # 总页数 'page_num': page_num, # 当前页码 } return render(request, 'list.html', context)
def get(self, request, category_id, page_num): #1、商品频道分类 categories = get_categories() cat3 = GoodsCategory.objects.get(id=category_id) #2、面包屑组件 breadcrumb = get_breadcrumb(cat3) #3、排序 #接收参数 sort = request.GET.get('sort') if sort == 'price': sort_field = 'price' elif sort == 'hot': sort_field = '-sales' else: sort_field = 'create_time' skus = SKU.objects.filter(category=cat3, is_launched=True).order_by(sort_field) #4、分页 #一页显示几个 paginator = Paginator(skus, 5) #总页数 all_pages = paginator.num_pages #当前页显示的内容 page_skus = paginator.page(page_num) #5、热销商品排行 #按照销量排序 #返回给前端的数据 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sort': sort, # 排序字段 'category': cat3, # 第三级分类 'page_skus': page_skus, # 分页后数据 'total_page': all_pages, # 总页数 'page_num': page_num, # 当前页码 } return render(request, 'list.html', context)
def get(self, request, category_id, page_num): try: category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return render(request, '404.html') sort = request.GET.get('sort', 'default') categories = get_categories() breadcrumb = get_breadcrumb(category) if sort == 'price': sort_field = 'price' elif sort == 'hot': sort_field = '-sales' else: sort = 'default' sort_field = 'create_time' skus = SKU.objects.filter(category=category, is_launched=True).order_by(sort_field) # data = SKU.objects.filter(category_id=category_id) paginator = Paginator(object_list=skus, per_page=5, ) page_skus = paginator.page(page_num) 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)
def get(self, request, category_id): try: cat3 = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return http.HttpResponseForbidden('类别id不存在') page_num = request.GET.get('page_num') or 1 page_size = request.GET.get('page_size') or 5 # 获取查询参数中的排序规则 sort = request.GET.get('sort') if sort == 'price': sort_filed = 'price' elif sort == 'hot': sort_filed = 'sales' else: sort = 'default' sort_filed = '-create_time' # 查询指定三级类别下的所有sku sku_qs = cat3.sku_set.filter(is_launched=True).order_by(sort_filed) paginator = Paginator(sku_qs, page_size) # 创建分页对象 try: page_skus = paginator.page(page_num) # 返回指定页的数据 except EmptyPage: return http.HttpResponseForbidden('没有下一页了') context = { 'categories': get_categories(), # 频道分类 'breadcrumb': get_breadcrumb(cat3), # 面包屑导航 'sort': sort, # 排序字段 'category': cat3, # 第三级分类 'page_skus': page_skus, # 分页后数据 'total_page': paginator.num_pages, # 总页数 'page_num': page_num # 当前页码 } return render(request, 'list.html', context)
def get(self, request, category_id, page_num): """ 我们需要根据当前的分类id,来获取它的上级/下级信息 """ # 一.面包屑实现 try: # 1.获取当前的分类id,并得到分类对象 category = GoodsCategory.objects.get(id=category_id) except Exception as e: logger.error(e) return render(request, 'list.html', context={'errmsg': '没有此分类'}) # 2.获取它的上级/下级 # 如果是一级 一个信息 # 如果是二级 两个信息 # 如果是三级 三个信息 breadcrumb = get_breadcrumb(category) # 二.列表数据 # 1.如果有排序字段再进行排序 sort = request.GET.get('sort') # sort = hot 人气 默认按销量进行排序 # sort = price 价格 根据 价格排序 # sort = default 默认 根据 create_time排序 if sort == 'hot': order_filed = 'sales' elif sort == 'price': order_filed = 'price' else: order_filed = 'create_time' sort = 'default' # 2.根据分类id, 把所有数据都查询出来 skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by(order_filed) # 3.如果有分页字段再分页 try: page_num = int(page_num) except: page_num = 1 # 3.1导入分页类 from django.core.paginator import Paginator try: # 3.2创建分页实例对象 paginator = Paginator(skus, 5) # 3.3获取分页数据 page_skus = paginator.page(page_num) # 总分页 total_page = paginator.num_pages except Exception as e: pass context = { 'category': category, 'breadcrumb': breadcrumb, 'sort': sort, # 排序字段 'page_skus': page_skus, # 分页后数据 'total_page': total_page, # 总页数 'page_num': page_num, # 当前页码 } return render(request, 'list.html', context)
def generate_static_sku_detail_html(sku): # 1.获取数据 # 查询商品频道分类 categories = get_categories() # 查询面包屑导航 n:1-->sku.外键属性 breadcrumb = get_breadcrumb(sku.category) # 构建当前商品的规格键 sku_specs = sku.specs.order_by('spec_id') sku_key = [] for spec in sku_specs: sku_key.append(spec.option.id) # 获取当前商品的所有SKU n:1-->sku.外键属性 skus = sku.spu.sku_set.all() # 构建不同规格参数(选项)的sku字典 spec_sku_map = {} for s in skus: # 获取sku的规格参数 s_specs = s.specs.order_by('spec_id') # 用于形成规格参数-sku字典的键 key = [] for spec in s_specs: key.append(spec.option.id) # 向规格参数-sku字典添加记录 spec_sku_map[tuple(key)] = s.id # 获取当前商品的规格信息 goods_specs = sku.spu.specs.order_by('id') # 若当前sku的规格信息不完整,则不再继续 if len(sku_key) < len(goods_specs): return for index, spec in enumerate(goods_specs): # 复制当前sku的规格键 key = sku_key[:] # 该规格的选项 spec_options = spec.options.all() for option in spec_options: # 在规格参数sku字典中查找符合当前规格的sku key[index] = option.id option.sku_id = spec_sku_map.get(tuple(key)) spec.spec_options = spec_options # 渲染页面 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, 'specs': goods_specs, } # 2.获取模板文件 template = loader.get_template('detail.html') # 3.渲染数据 html_text = template.render(context) # 4.写入本地文件 'detail/{}.html'.format(sku.id)--拼接字符串 {}取sku.id的值 file_path = os.path.join(settings.STATICFILES_DIRS[0], 'detail/{}.html'.format(sku.id)) print(file_path) with open(file_path, 'w') as f: f.write(html_text)
def get(self, request, category_id): """ 提供商品列表数据和面包屑导航数据 :param category_id: 商品三级分类 :return: JSON """ # 1.接收参数 # 当前用户想看的页码 page_num = request.GET.get("page") # 该页中想看的记录的个数 page_size = request.GET.get("page_size") # 排序字段 ordering = request.GET.get("ordering") # 2.校验参数 # 校验category_id是否存在 try: category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return http.JsonResponse({"code": 400, "errmsg": "category_id不存在"}) # page_num、page_size、ordering不需要单独校验,因为是在排序和分页时校验的 # 3.实现核心逻辑:排序和分页、面包屑导航 # 查询指定分类下,未被下架的SKU信息 skus = SKU.objects.filter(category=category, is_launched=True).order_by(ordering) # 分页查询 # 创建分页器对象:分页器对象 = Paginator(要分页的查询集,每页记录个数) paginator = Paginator(skus, page_size) # 获取指定页中的模型数据:paginator.page(页码) # 为了保证page_num在范围内不越界,所以要try,不然就是空页 try: page_skus = paginator.page(page_num) except EmptyPage: return http.JsonResponse({"code": 400, "errmsg": "页码错误"}) # 获取分页后的总页数 total_pages = paginator.num_pages # 将分页后的查询集转列表(为了jsonresponse能识别) list = [] for sku in page_skus: list.append({ "id": sku.id, "default_image_url": sku.default_image.url, "name": sku.name, "price": sku.price, }) # 面包屑导航 breadcrumb = get_breadcrumb(category) # 4.响应结果 return http.JsonResponse({ "code": 0, "errmsg": "OK", "breadcrumb": breadcrumb, # 面包屑当行 "list": list, # 排序后的分页数据,不是模型数据,因为jsonresponse不识别 "count": total_pages, # 分页后的总页数 })
def get_detail_html(sku_id): # 获取当前sku对象 sku=SKU.objects.get(id=sku_id) # 分类数据 categories = get_categories() # 获取面包屑导航 breadcrumb = get_breadcrumb(sku.category) # 获取spu spu = sku.spu # 获取规格信息:sku===>spu==>specs specs = spu.specs.order_by('id') # 查询所有的sku,如华为P10的所有库存商品 skus = spu.skus.order_by('id') ''' { 选项:sku_id } 说明:键的元组中,规格的索引是固定的 示例数据如下: { (1,3):1, (2,3):2, (1,4):3, (2,4):4 } ''' sku_options = {} sku_option = [] for sku1 in skus: infos = sku1.specs.order_by('spec_id') option_key = [] for info in infos: option_key.append(info.option_id) # 获取当前商品的规格信息 if sku.id == sku1.id: sku_option.append(info.option_id) sku_options[tuple(option_key)] = sku1.id # 遍历当前spu所有的规格 specs_list = [] for index, spec in enumerate(specs): option_list = [] for option in spec.options.all(): # 如果当前商品为蓝、64,则列表为[2,3] sku_option_temp = sku_option[:] # 替换对应索引的元素:规格的索引是固定的[1,3] sku_option_temp[index] = option.id # 为选项添加sku_id属性,用于在html中输出链接 option.sku_id = sku_options.get(tuple(sku_option_temp), 0) # 添加选项对象 option_list.append(option) # 为规格对象添加选项列表 spec.option_list = option_list # 重新构造规格数据 specs_list.append(spec) context = { 'sku': sku, 'categories': categories, 'breadcrumb': breadcrumb, 'category_id': sku.category_id, 'spu': spu, 'specs': specs_list } response = render(None, 'detail.html', context) file_name = os.path.join(settings.BASE_DIR, 'static/detail/%d.html' % sku.id) # 写文件 with open(file_name, 'w') as f1: f1.write(response.content.decode())