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() # 查詢麵包屑導航 breadcrump = 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': breadcrump, 'sku': sku, 'specs': goods_specs, } return render(request, 'detail.html', context)
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(16)的所有具体规格对象(颜色6:黑16, 版本7:128G21) current_sku_spec_qs = sku.specs.order_by('spec_id') # 此sku所有规格的id列表 current_sku_option_ids = [] for current_sku_spec in current_sku_spec_qs: current_sku_option_ids.append( current_sku_spec.option_id) # [16, 21] # 获取当前spu下的所有sku temp_sku_qs = sku.spu.sku_set.all() spec_sku_map = {} # 用来构造sku规格仓库 for temp_sku in temp_sku_qs: # 查询所有sku的具体规格对象 temp_spec_qs = temp_sku.specs.order_by('spec_id') temp_sku_option_ids = [] # 用来包装sku所有规格的id 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 # {(16,20): 15, (16,21): 16} # 获取当前spu(3)中的所有规格对象(颜色6, 版本7) spu_spec_qs = sku.spu.specs.order_by('id') for index, spec in enumerate(spu_spec_qs): # 获取当前spu规格(6)中的所有选项对象 spec_option_qs = spec.options.all() # (13,14,15,16) # 复制一个新的当前sku(16)的规格id列表 temp_option_ids = current_sku_option_ids[:] # [16,21] for option in spec_option_qs: temp_option_ids[index] = option.id # 13 # 给每个spu选项对象绑定sku_id属性 option.sku_id = spec_sku_map.get( tuple(temp_option_ids)) # sku16 # 把spu规格下的所有选项绑定到规格对象的spec_options属性上 spec.spec_options = spec_option_qs context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, 'category': sku.category, 'spu': sku.spu, 'spec_qs': spu_spec_qs # 当前spu的所有规格数据 } return render(request, 'detail.html', context)
def get(self, request, category_id, page_num): """ 提供当前三级类别下的所有商品(SKU)列表页 :param category_id: 三级类别ID :param page_num: 查询页码 :return: """ # 判断category_id是否正确 try: category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return http.HttpResponseNotFound('category_id不存在') # 接收sort参数,默认排序方式为default 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' # 获取当前三级类别下的所有SKU,三级类别与SKU为一对多 skus = SKU.objects.filter(category=category, is_launched=True).order_by(sort_field) # 创建分页器:每页N条记录 paginator = Paginator(skus, constants.GOODS_LIST_LIMIT) # 获取列表页总页数 total_page = paginator.num_pages try: # 获取当前页的SKU数据 page_skus = paginator.page(page_num) except EmptyPage: # 如果page_num不正确,默认给用户404 return http.HttpResponseNotFound('空页面') context = { 'categories': categories, # 所有商品类别 'breadcrumb': breadcrumb, # 面包屑导航 'category': category, # 第三级分类的商品 'total_page': total_page, # 总页数 'page_num': page_num, # 当前页码 'page_skus': page_skus, # 当前页的所有SKU数据 'sort': sort, # 排序字段 } return render(request, 'list.html', context)
def get(self, request, sku_id): """提供商品详情页""" # 获取当前sku的信息 try: sku = models.SKU.objects.get(id=sku_id) except models.SKU.DoesNotExist: return render(request, '404.html') # 查询商品频道分类 categories = get_categories() # 查询面包屑导航 breadcrumb = get_beradcrumb(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=context)
def get(self, request, sku_id): # 接收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) # 获取当前商品的所有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_spacs = sku.spu.specs.order_by('id') # 若当前sku信息不完整,则不再继续 if len(sku_key) < len(goods_spacs): return render(request, '404.html') for index, spec in enumerate(goods_spacs): 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_spacs, } return render(request, 'detail.html', context)
def generate_static_sku_detail_html(sku_id): sku = SKU.objects.get(id=sku_id) category = sku.category # 获取当前sku所对应的三级分类 # 查询当前sku所对应的spu spu = sku.spu """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': get_categories(), # 商品分类 'breadcrumb': get_breadcrumb(category), # 面包屑导航 'sku': sku, # 当前要显示的sku模型对象 'category': category, # 当前的显示sku所属的三级类别 'spu': spu, # sku所属的spu 'spec_qs': spu_spec_qs, # 当前商品的所有规格数据 } response = render(None, 'detail.html', context) html_text = response.content.decode() 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): try: sku = SKU.objects.get(id=sku_id) except SKU.DoesNotExist: return render(request, '404.html') category = sku.category # 获取当前sku所对应的三级分类 # 查询当前sku所对应的spu spu = sku.spu """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': get_categories(), # 商品分类 'breadcrumb': get_breadcrumb(category), # 面包屑导航 'sku': sku, # 当前要显示的sku模型对象 'category': category, # 当前的显示sku所属的三级类别 'spu': spu, # sku所属的spu 'spec_qs': spu_spec_qs, # 当前商品的所有规格数据 } return render(request, 'detail.html', context)
def get(self, request, category_id, page_num): """查詢並渲染商品表""" try: category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: http.HttpResponseForbidden('參數category_id不存在') # 獲取sort排序, 如果sort沒有值, 默認取default sort = request.GET.get('sort', 'default') # 根據sort選擇排序欄位,欄位必須是模型類的屬性 if sort == 'price': sort_field = 'price' # 價格低到高 elif sort == 'hot': sort_field = '-sales' # 銷量高到低 else: sort = 'default' sort_field = 'create_time' # 查詢商品分類 categories = get_categories() # 麵包屑導航 breadcrumb = get_breadcrumb(category) # 分頁和排序查詢 category查詢sku 一對多 #skus = SKU.objects.filter(category=category, is_launched=True).order_by(sort_field) skus = category.sku_set.filter(is_launched=True).order_by(sort_field) # 創建分頁器 paginator = Paginator(skus, 5) try: # 獲取用戶當前要看的那頁紀錄 page_skus = paginator.page(page_num) except EmptyPage: return http.HttpResponseNotFound('Empty page') # 總頁數 total_pages = paginator.num_pages context = { 'categories': categories, 'breadcrumb': breadcrumb, 'page_skus': page_skus, 'total_page': total_pages, 'page_num': page_num, 'sort': sort, 'category_id': category_id, } return render(request, 'list.html', context)
def get(self, request, sku_id): # 获取当前sku的信息 try: sku = SKU.objects.get(id=sku_id) except Exception as e: return http.HttpResponseForbidden("sku_id 不存在") # 获取当前sku所对应的三级分类 category = sku.category # 查询当前sku所对应的spu spu = sku.spu """1.准备当前商品的规格选项列表 [8, 11]""" # 获取出当前正显示的sku商品的规格选项id列表 sku_spec_qs = sku.specs.order_by('spec_id') sku_option_ids = [] for sku_spec in sku_spec_qs: sku_option_ids.append(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 = {} 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 = sku_option_ids[:] for option in spec_option_qs: temp_option_ids[index] = option.id option.sku_id = spec_sku_map.get(tuple(temp_option_ids)) spec.spec_options = spec_option_qs # 查询商品频道分类 categories = get_categories() # 查询面包屑导航 breadcrumb = get_breadcrumb(category) # 渲染页面 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, 'spu': spu, 'spec_qs': spu_spec_qs, 'category': category } return render(request, 'detail.html', context)
def get(self, request, category_id, page_num): """查询并渲染商品列表页""" # 校验参数category_id的范围 : 1111111111111111111111111111111 try: # 三级类别 category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return http.HttpResponseForbidden('参数category_id不存在') # 获取sort(排序规则): 如果sort没有值,取'default' sort = request.GET.get('sort', 'default') # 根据sort选择排序字段,排序字段必须是模型类的属性 if sort == 'price': sort_field = 'price' # 按照价格由低到高排序 elif sort == 'hot': sort_field = '-sales' # 按照销量由高到低排序 else: # 只要不是'price'和'-sales'其他的所有情况都归为'default' sort = 'default' # 当出现?sort=itcast 也把sort设置我'default' sort_field = 'create_time' # 查询商品分类 categories = get_categories() # 查询面包屑导航:一级 -> 二级 -> 三级 breadcrumb = get_breadcrumb(category) # 分页和排序查询:category查询sku,一查多,一方的模型对象.多方关联字段.all/filter # skus = SKU.objects.filter(category=category, is_launched=True) # 无经验查询 # skus = SKU.objects.filter(category_id=category_id, is_launched=True) # 无经验查询 # skus = category.sku_set.filter(is_launched=True).order_by('排序字段:create_time,price,-sales') # 有经验查询 skus = category.sku_set.filter(is_launched=True).order_by(sort_field) # 有经验查询 # 创建分页器 # Paginator('要分页的记录', '每页记录的条数') paginator = Paginator(skus, 5) # 把skus进行分页,每页5条记录 # 获取到用户当前要看的那一页(核心数据) try: page_skus = paginator.page(page_num) # 获取到page_num页中的五条记录 except EmptyPage: return http.HttpResponseNotFound('Empty Page') # 获取总页数:前端的分页插件需要使用 total_page = paginator.num_pages # 构造上下文 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'page_skus': page_skus, 'total_page': total_page, 'page_num': page_num, 'sort': sort, 'category_id': category_id } 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') # 通过sku获取三级目录商品 category = sku.category # categories = get_categories() # breadcrumb = get_breadcrumb(category) spu = sku.spu # 1, 获得当前sku的规格 current_sku_spec_qs = sku.specs.order_by('spec_id') current_sku_option_ids = [] for current_sku_spec in current_sku_spec_qs: current_sku_option_ids.append(current_sku_spec.option_id) # 2, 获得spu的所有规格包装 # 获得所有spu下的sku sku_qs = spu.sku_set.all() # {(8,11): 3, (8,12): 4....} all_spec_dict = {} for every_sku in sku_qs: # 查每个sku对应的规格 every_sku_spec_qs = every_sku.specs.order_by('spec_id') every_sku_option_ids = [] for every_sku_spec in every_sku_spec_qs: every_sku_option_ids.append(every_sku_spec.option_id) all_spec_dict[tuple(every_sku_option_ids)] = every_sku.id # 3, 与 sku_id进行绑定 # 获取此商品对应spu的所有规格名称 spu_spec_qs = spu.specs.order_by('id') # 遍历spu的所有规格得到每一个规格, 其属性就是每个规格对应的所有规格值, for index, spu_spec in enumerate(spu_spec_qs): spu_option_qs = spu_spec.options.all() temp_option_ids = current_sku_option_ids[:] for option in spu_option_qs: temp_option_ids[index] = option.id option.sku_id = all_spec_dict.get(tuple(temp_option_ids)) spu_spec.spu_option = spu_option_qs context = { 'categories': get_categories(), 'breadcrumb': get_breadcrumb(category), 'sku': sku, 'spu_spec_qs': spu_spec_qs, 'spu': spu, 'category': category } return render(request, 'detail.html', context)
def get(self, request, category_id, page_num): """提供商品列表页""" # 校验参数 # 校验category_id的范围 try: # 三级类别 category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist as e: logger.error(e) return http.HttpResponseForbidden('参数category_id不存在') # 获取sort(排序规则) sort = request.GET.get('sort', 'default') # 根据sort选择排序字段,排序字段必须是模型类的属性 # 按照价格 if sort == 'price': sort_field = 'price' # 按照销量 elif sort == 'hot': sort_field = '-sales' else: # 当出现?sort = xlz sort=default sort = 'default' sort_field = 'create_time' # 查询商品分类 categories = get_categories() # 查询面包屑导航 一级-二级-三级 breadcrumb = get_breadcrumb(category) # 排序category查询sku,一查多 skus = category.sku_set.filter(is_launched=True).order_by(sort_field) # 分页 # 创建分页器 # Paginator('要分页的记录', '每页的条数') paginator = Paginator(skus, settings.HAYSTACK_SEARCH_RESULTS_PER_PAGE) # 获取用户当前要看的那一页(核心) try: page_skus = paginator.page(page_num) except EmptyPage as e: logger.error(e) return http.HttpResponseNotFound('空的页面') # 获取总页数:前端需要使用 total_page = paginator.num_pages # 构造上下文 context = { 'categories': categories, # 频道分类 'breadcrumb': breadcrumb, # 面包屑导航 'page_skus': page_skus, # 分页后数据 'total_page': total_page, # 总页数 'page_num': page_num, # 当前页码 'sort': sort, # 排序字段 'category': category, # 第三级分类 'category_id': category_id # 第三级分类id } return render(request, 'list.html', context)
def get(self, request, category_id, page_num): # 包装面包屑导航数据 try: cat3 = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return http.HttpResponseForbidden('category_id不存在') # # 给cat1定义一个url # cat1 = cat3.parent.parent # cat1.url = cat1.goodschannel_set[0].url # # # 用来装面包屑数据 # breadcrumb = { # 'cat3': cat3, # 'cat2': cat3.parent, # 'cat1': cat1 # } # 指定排序规则 sort = request.GET.get('sort', 'default') if sort == 'price': sort_fields = '-price' elif sort == 'hot': sort_fields = '-sales' else: sort = 'default' sort_fields = '-create_time' # 排序字段 # 数据分页 # 获取当前三级类型下的所有sku sku_qs = cat3.sku_set.filter(is_launched=True).order_by(sort_fields) # 创建分页器对象 参数 (要分页的所有数据, 每页显示多少条数据) paginator = Paginator(sku_qs, 5) # 获取总页数 total_page = paginator.num_pages # 获取指定页面的数据 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': total_page, # 总页数 'page_num': page_num, # 当前页码 } return render(request, 'list.html', context)
def get(self, request, category_id, page_num): """ 商品列表页面 :param request: :return: """ # 判断category_id是否正确 try: category = GoodsCategory.objects.get(id=category_id) except Exception as e: logger.error(e) return http.HttpResponseNotFound('category_id 不存在') # 接收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: sort = 'default' sort_field = 'create_time' # 分页和排序查询:category查询sku,一查多,一方的模型对象.多方关联字段.all/filter skus = category.sku_set.filter(is_launched=True).order_by(sort_field) # 创建分页器: 每页page_num条记录 paginator = Paginator(skus, constants.GOODS_LIST_LIMIT) try: page_skus = paginator.page(page_num) except EmptyPage: 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)
def get(self, request, category_id, page_num): try: # 获取分组 category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return http.HttpResponseNotFound('GoodsCategory 不存在') # 查询商品频道分类 categories = get_categories() breadcrumb = get_breadcrumb(category) # 获取排序规则 sort = request.GET.get('sort', 'default') # 按照排序规则查询该分类商品SKU信息 if sort == 'price': # 按照价格由低到高 sortkind = 'price' elif sort == 'hot': # 按照销量由高到低 sortkind = '-sales' else: # 'price'和'sales'以外的所有排序方式都归为'default' sort = 'default' sortkind = 'create_time' # 获取当前分类并且上架的商品.( 并且对商品按照排序字段进行排序 ) skus = SKU.objects.filter(category=category, is_launched=True).order_by(sortkind) # 创建分页器:每页N条记录 # # 列表页每页商品数据量 # GOODS_LIST_LIMIT = 5 paginator = Paginator(skus, 5) # 获取每页商品数据 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)
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') # 接收sort参数:如果用户不传,就是默认的排序规则 sort = request.GET.get('sort', 'default') # 按照排序规则查询该分类商品SKU信息 if sort == 'price': # 按照价格由低到高 sort_field = 'price' elif sort == 'hot': # 按照销量由高到低 sort_field = '-sales' else: # 'price'和'sales'以外的所有排序方式都归为'default' sort = 'default' sort_field = 'create_time' # 查询商品频道分类 categories = get_categories() # 查询面包屑导航 breadcrumb = get_breadcrumb(category) skus = category.sku_set.filter(is_launched=True).order_by(sort_field) # skus = SKU.objects.filter(category_id=category_id, is_launched=True) # 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 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)
def get(self, request, category_id, page_num): ''' :param request: :param category_id: 商品id :param page_num: 页码 :return: ''' categories = get_categories() try: category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return http.HttpResponseForbidden('缺少category_id参数') breadcrumb = get_breadcrumb(category) # 接收sort参数:如果用户不传,就是默认的排序规则 sort = request.GET.get('sort', 'default') # 按照排序规则查询该分类商品SKU信息 if sort == 'price': # 按照价格由低到高 sort_field = 'price' elif sort == 'hot': # 按照销量由高到低 sort_field = '-sales' else: # 'price'和'sales'以外的所有排序方式都归为'default' sort = 'default' sort_field = '-create_time' skus = category.skus.filter(is_launched=True).order_by(sort_field) paginator = Paginator(skus, 5) # 获取每页商品数据 try: page_skus = paginator.page(page_num) except EmptyPage: # 如果page_num不正确,默认给用户404 return http.HttpResponseNotFound('页面不存在') # 获取列表页总页数 total_page = paginator.num_pages context = { 'categories': categories, 'breadcrumb': breadcrumb, 'page_skus': page_skus, 'sort': sort, 'total_page': total_page, 'page_num': page_num, 'category_id': category_id } return render(request, 'list.html', context)
def get(self,request,category_id,page_num): '''提供列页''' # 校验参数 try: # 三级类别 category = GoodsCategory.objects.get(id=category_id) except Exception as e: return http.HttpResponseNotFound('GoodsCategory does not exist') # 面包屑导航 beradcrumb = get_beradcrumb(category) # 查询商品分类 categories = get_categories() # 接收排序规则 sort = request.GET.get('sort', 'default') # 按照排序规则查询该分类商品SKU信息 # 注意一定是模型字段里的 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) # 商品分页,创建分页器 paginator = Paginator(skus, 5) # 把skus分页,默认每页5条 # 获取当前用户要查看的那一页 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, 'beradcrumb' : beradcrumb, # 面包屑导航 'page_skus' : page_skus, #当前页面的商品种类 'total_page' : total_page, # 总页数 'page_num' : page_num, # 当前页面 'sort' : sort, # 排序规则 'category_id' : category_id, # 商品id } 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.HttpResponseForbidden('参数category_id不存在') # 获取sort参数:如果sort没有值,取'default' sort = request.GET.get('sort', 'default') # 根据sort选择排序字段,排序字段必须是模型类的属性 if sort == 'price': sort_field = 'price' # 按照价格由低到高排序 elif sort == 'hot': sort_field = '-sales' # 按照销量由高到低排序 else: # 只要不是'price'和'-sales'其他的所有情况都归为'default' sort = 'default' sort_field = 'create_time' # 当出现?sort=itcast 也把sort设置我'default' # 查询首页商品分类 categories = get_categories() # 查询面包屑导航:一级/二级/三级 breadcrumb = get_breadcrumb(category) # 分页和排序查询: category查询sku 一查多:一类模型对象.多类模型类名小写_set.filter # 查询商品已上架 并按字段进行排序 skus = category.sku_set.filter(is_launched=True).order_by(sort_field) # 创建分页器 # Paginator('要分页的记录', '每页记录的条数') paginator = Paginator(skus, constants.GOODS_LIST_LIMIT) # 把skus进行分页,每页显示5条记录 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, # 面包屑导航 'page_skus': page_skus, # 要分页的数据 'total_page': total_page, # 总页数 'page_num': page_num, # 所在页 'category_id': category_id, # 三级分类id 'sort': sort # 排序字段 } # 响应结果 return render(request, 'list.html', context)
def get(self, request ,sku_id ): """提供商品詳情頁面""" #接收並校驗參數 try: sku = SKU.objects.get(id=sku_id, is_launched=True) except Exception: return render(request, '404.html') #查詢商品分類 categories = get_categories() #查詢麵包屑導航 breadcrumb = get_breadcrumb(sku.category) #查詢當前商品規格 goods = sku.goods #建立當前商品規格鍵 sku_specs = sku.skuspecification_set.order_by('spec_id') sku_key = [] # [規格1,規格2,..] for spec in sku_specs: sku_key.append(spec.option_id) #取出當前商品所有規格鍵和對應sku_id建立字典 skus = sku.goods.sku_set.all() key_sku_map = {} for s in skus: s_specs = s.skuspecification_set.order_by('spec_id') key = [] for spec in s_specs: key.append(spec.option_id) key_sku_map[tuple(key)] = s.id # {(規格1,規格2,..):sku_id,..) #獲取當前商品規格對象 goods_specs = goods.goodsspecification_set.order_by('id') for index, spec in enumerate(goods_specs): #複製當前規格鍵 key = sku_key[:] options = spec.specificationoption_set.all() for option in options: #查出當前商品對應的規格對象 key[index] = option.id #從字典找出sku_id賦值 option.sku_id = key_sku_map.get(tuple(key)) spec.spec_options = options #網頁訪問不須登入,所以設置csrftoken get_token(request) #構造響應數據 context = { 'categories':categories , 'breadcrumb':breadcrumb , 'sku':sku , 'specs':goods_specs , 'category_id':sku.category.id , } 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") category = sku.category spu = sku.spu """1 准备当前商品的规格选项列表""" # 获取出当前正在显示的sku商品的规格选项Id列表 current_sku_spec_qs = sku.specs.order_by("spec_id") current_sku_options_ids = [] for current_sku_spec in current_sku_spec_qs: current_sku_options_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() # 选项仓库大字典 spec_sku_map = {} for temp_sku in temp_sku_qs: temp_spec_qs = temp_sku.specs.order_by("spec_id") temp_sku_option_ids = [] 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") for index, spec in enumerate(spu_spec_qs): spec_option_qs = spec.options.all() temp_option_ids = current_sku_options_ids[:] for option in spec_option_qs: temp_option_ids[index] = option.id option.sku_id = spec_sku_map.get(tuple(temp_option_ids)) spec.spec_options = spec_option_qs category = sku.category context = { "categories": get_categories(), # 商品分类 "breadcrumb": get_breadcrumb(category), # 面包屑导航 "sku": sku, # 当前要显示的sku模型对象 "spu": sku.spu, # sku所属的spu "category": category, # 当前的显示sku所属的三级列别 "spec_qs": spu_spec_qs, # 当前商品的所有规格数据 } return render(request, "detail.html", context)
def generate_static_sku_detail_html(sku_id): """批量生成商品詳情頁靜態頁面""" #獲取SKU sku = SKU.objects.get(id=sku_id, is_launched=True) #查詢商品分類 categories = get_categories() #查詢麵包屑導航 breadcrumb = get_breadcrumb(sku.category) #查詢當前商品規格 goods = sku.goods #建立當前商品規格鍵 sku_specs = sku.skuspecification_set.order_by('spec_id') sku_key = [] #[規格1,規格2,..] for spec in sku_specs: sku_key.append(spec.option_id) #取出當前商品所有規格鍵和對應sku_id建立字典 skus = sku.goods.sku_set.all() key_sku_map = {} for s in skus: s_specs = s.skuspecification_set.order_by('spec_id') key = [] for spec in s_specs: key.append(spec.option_id) key_sku_map[tuple(key)] = s.id # {(規格1,規格2,..):sku_id,..) #獲取當前商品規格對象 goods_specs = goods.goodsspecification_set.order_by('id') for index, spec in enumerate(goods_specs): #複製當前規格鍵 key = sku_key[:] options = spec.specificationoption_set.all() for option in options: #查出當前商品對應的規格對象 key[index] = option.id #從字典找出sku_id賦值 option.sku_id = key_sku_map.get(tuple(key)) spec.spec_options = options #構造響應數據 context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, 'specs': goods_specs, 'category_id': sku.category.id, } template = loader.get_template('detail.html') html_text = template.render(context) file_path = os.path.join(settings.STATICFILES_DIRS[0], 'details/' + str(sku_id) + '.html') with open(file_path, 'w') as f: f.write(html_text)
def get(self, request, categorie_id, page_num): """渲染列表页""" # categorie_id 三级分类的id # page_num:页数 #频道分类数据 categories = get_categories() cat3 = GoodsCategory.objects.get(id=categorie_id) cat2 = cat3.parent cat1 = cat2.parent #一级分类额外指定url路径 cat1.url = cat1.goodschannel_set.filter()[0].url breadcrumb = {} breadcrumb["cat1"] = cat1 breadcrumb["cat2"] = cat2 breadcrumb["cat3"] = cat3 #渲染当前分类下的所有商品 # 获取排序字段 sort = request.GET.get("sort") if sort is None or sort == "create_time": sort = "create_time" #默认排序 skus = SKU.objects.filter( category_id=categorie_id).order_by("create_time") elif sort == "price": #按价格排序 skus = SKU.objects.filter( category_id=categorie_id).order_by("price") else: #按照销量排序 skus = SKU.objects.filter( category_id=categorie_id).order_by("sales") #分页 page = Paginator(skus, 5) #每页5个 page_skus = page.page(page_num) #第几页开始 data = { "categories": categories, #按频道分类数据 "breadcrumb": breadcrumb, #面包写导航数据 "page_skus": page_skus, #分页后的商品数据 "category": cat3, #分类对象 "page_num": page_num, #当前页数 "total_page": page.num_pages, #总页数 "sort": sort #排序字段 } return render(request, "list.html", data)
def get(self, request, category_id, page_num): """获取商品列表页""" # 1. 测试此商品类别是否存在 try: category = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return http.HttpResponseForbidden('参数id不存在') # 2. 查询商品分类数据 categories = get_categories() # 3. 查询商品面包屑导航 breadcrumb = get_breadcrumb(category) # 4. 按照排序规则查询该分类商品SKU信息 sort = request.GET.get('sort', 'default') # 这个排序必须拿的是模型类里定义的字段 if sort == 'price': sort_field = 'price' elif sort == 'hot': sort_field = '-sales' else: sort = 'default' sort_field = 'create_time' # 一查多(使用【“一”的模型类对象】.【多的模型类名小写_set】.【查询方法】) skus = category.sku_set.filter(is_launched=True).order_by(sort_field) # skus = SKU.objects.filter(category=category, is_launched=True).order_by(sort_field) # 5. 添加分页查询功能 # 创建分页器 paginator = Paginator(skus, 5) # 分成5页 # 获取每页商品数据 try: # 获取当前页数的数据 page_skus = paginator.page(page_num) except EmptyPage: 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)
def get(self, request, category_id, page_num): try: cat3 = GoodsCategory.objects.get(id=category_id) except GoodsCategory.DoesNotExist: return http.HttpResponseForbidden('类别id不存在') # cat1 = cat3.parent.parent # # 给一级类别定义url属性 # cat1.url = cat1.goodschannel_set.all()[0].url # # 包装面包屑导航数据 # breadcrumb = { # 'cat1': cat1, # 'cat2': cat3.parent, # 'cat3': cat3 # } # 获取查询参数中的排序规则 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) # sku_qs = SKU.objects.filter(category_id=category_id, is_launched=True).order_by(sort_filed) # page = total_count / 5 + (1 if total % 5 else 0) # 计算总页数 # sa = 5 * (page_num - 1) # sku_qs[sa : (sa + (5 - 1))] # 计算显得指定页角标 paginator = Paginator(sku_qs, 5) # 创建分页对象 try: page_skus = paginator.page(page_num) # 返回指定页的数据 except EmptyPage: return http.HttpResponseForbidden('没有下一页了') total_page = paginator.num_pages # 获取总页数 context = { 'categories': get_categories(), # 频道分类 'breadcrumb': get_breadcrumb(cat3), # 面包屑导航 '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 Exception as e: return render(request, '404.html') categories = get_categories() breadcrumb = get_breadcrumb(category=sku.category) context = { 'categories': categories, 'breadcrumb': breadcrumb, 'sku': sku, } return render(request, 'detail.html',context)
def get(self, request): # 定义一个大字典用来装所有广告 contents = {} # 获取出所有广告类别数据 content_category_qs = ContentCategory.objects.all() for content_category in content_category_qs: # 包装每种类型的广告数据 contents[content_category.key] = content_category.content_set.filter(status=True).order_by('sequence') # 包装要渲染的数据 context = { 'categories': get_categories(), # 商品分类数据 'contents': contents, # 广告内容 } return render(request, 'index.html', context)
def get(self, request, categorie_id, page_num): categories = get_categories() # 渲染密保寫導航數據 # 面包屑导航数据 cat3 = GoodsCategory.objects.get(id=categorie_id) cat2 = cat3.parent cat1 = cat2.parent # 一级分类额外指定url路径 cat1.url = cat1.goodschannel_set.filter()[0].url breadcrumb = {} breadcrumb['cat1'] = cat1 breadcrumb['cat2'] = cat2 breadcrumb['cat3'] = cat3 # 渲染當前分類下的所有上平 # 獲取排序字段 sort = request.GET.get('sort') if sort is None or sort == 'create_time': sort = 'create_time' # 默認排序 skus = SKU.objects.filter( category_id=categorie_id).order_by('create_time') elif sort == 'price': skus = SKU.objects.filter( category_id=categorie_id).order_by('price') # 按照銷量排序 else: skus = SKU.objects.filter( category_id=categorie_id).order_by('sales') #分也 # page = Paginator(skus, 5) page_skus = page.page(page_num) data = { # 平道分類 蜜毛包鞋 分頁後的上平數據 分類對象 當前頁數 總頁數 排序 'categories': categories, 'breadcrumb': breadcrumb, 'page_skus': page_skus, 'category': cat3, 'page_num': page_num, 'total_page': page.num_pages, 'sort': sort } return render(request, 'list.html', data)
def get(self, request, sku_id): try: sku = SKU.objects.get(id=sku_id, is_launched=True) except SKU.DoesNotExist: return render(request, '404.html') spu = sku.spu # try: category = sku.category '''spu_spec_qs=[ {name:xxx, spec_options:[{sku_id: value:}],} ]''' current_sku_spec_qs = sku.specs.order_by('spec_id') current_sku_option_ids = [] for current_sku_spec in current_sku_spec_qs: current_sku_option_ids.append(current_sku_spec.option.id) current_spu_option_dict = {} for temp_sku in spu.sku_set.all(): temp_current_sku_spec_qs = temp_sku.specs.order_by('spec_id') temp_current_sku_option_ids = [] for temp_current_sku_spec in temp_current_sku_spec_qs: temp_current_sku_option_ids.append( temp_current_sku_spec.option.id) current_spu_option_dict[tuple( temp_current_sku_option_ids)] = temp_sku.id spu_spec_qs = spu.specs.order_by('id') for index, spu_spec in enumerate(spu_spec_qs): spu_spec.spec_options = spu_spec.options.all() temp_list = current_sku_option_ids[:] for spu_spec_options in spu_spec.spec_options: temp_list[index] = spu_spec_options.id spu_spec_options.sku_id = current_spu_option_dict.get( tuple(temp_list)) context = { 'categories': get_categories(), # 商品分类 'breadcrumb': get_breadcrumb(category), # 面包屑导航 'sku': sku, # 当前要显示的sku模型对象 'category': category, # 当前的显示sku所属的三级类别 'spu': spu, # sku所属的spu 'spec_qs': spu_spec_qs, # 当前商品的所有规格数据 } return render(request, 'detail.html', context)
def generate_static_list_html(): categories = get_categories() # 使用`detail.html`文件,进行模板渲染,获取渲染之后的内容 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)