Пример #1
0
    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)
Пример #2
0
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)
Пример #3
0
    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)
Пример #4
0
    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)
Пример #5
0
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)
Пример #6
0
    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)
Пример #7
0
    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)
Пример #8
0
    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  # 分页后的总页数
        })
Пример #9
0
    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)
Пример #10
0
    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)
Пример #11
0
    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)
Пример #12
0
    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)
Пример #13
0
    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)
Пример #14
0
 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)
Пример #15
0
    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)
Пример #16
0
    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)
Пример #17
0
    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)
Пример #18
0
    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)
Пример #19
0
    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)
Пример #20
0
    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)
Пример #21
0
    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)
Пример #22
0
    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)
Пример #23
0
    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)
Пример #24
0
    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)
Пример #25
0
    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)
Пример #26
0
    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)
Пример #27
0
    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)
Пример #28
0
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)
Пример #29
0
    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,  # 分页后的总页数
        })
Пример #30
0
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())