Django实战-生鲜电商-主页|商品

2019-07-18 16:05:32 浏览数 (1)

前面一小节完成了对登录、注册、激活的视图,需要注意的是,在逻辑处理上需要明确是采用何种方式实现浏览器的登录状态保存。

一、主页视图

在主页视图中,有用到缓存机制

  • 商品分类信息
  • 首页轮播图信息
  • 活动信息
  • 提供购物车数据统计功能

① 提供购物车数据统计功能

代码语言:javascript复制
class BaseCartView(View):
    """提供购物车数据统计功能"""
    def get_cart_num(self, request):
        cart_num = 0

        if request.user.is_authenticated():
            # 如果用户登录,
            # 从redis中获取用户的购物车数据
            redis_conn = get_redis_connection("default")
            user_id = request.user.id
            # 返回字典
            cart = redis_conn.hgetall("cart_%s" % user_id)
            # {"sku_1": "11", "sku_2": "10"}
            for value in cart.values():
                cart_num  = int(value)
        else:
            # 用户未登录,从cookie中获取购物车数据
            cart_json = request.COOKIES.get("cart")
            if cart_json is not None:
                cart = json.loads(cart_json)
            else:
                cart = {}

            # 遍历cart字典,对商品数量进行求和
            for val in cart.values():
                cart_num  = val

        return cart_num

② 主页

主页继承类 BaseCartView 提供购物车数据统计功能。

代码语言:javascript复制
class IndexView(BaseCartView):
    """主页"""
    def get(self, request):
        # 先尝试从缓存中读取数据
        context = {}

        # 如果缓存中没有数据,再查询
        if context is None:
            print("没有缓存数据, 查询了数据库")
            # 查询数据库,获取需要的数据放到模板中

            # 商品分类信息
            categorys = GoodsCategory.objects.all()

            # 首页轮播图信息, 按照index进行排序
            index_goods_banners = IndexGoodsBanner.objects.all().order_by("index")[:4]

            # 活动信息
            promotion_banners = IndexPromotionBanner.objects.all().order_by("index")[:2]

            # 分类商品信息
            for category in categorys:
                title_banners = IndexCategoryGoodsBanner.objects.filter(category=category, display_type=0).order_by("index")
                category.title_banners = title_banners

                image_banners = IndexCategoryGoodsBanner.objects.filter(category=category, display_type=1).order_by("index")
                category.image_banners = image_banners

            context = {
                "categorys": categorys,
                "index_banners": index_goods_banners,
                "promotion_banners": promotion_banners,
            }

        return render(request, "index.html", context)

二、商品列表视图

列表一般都会用到分页

如果总页数小于5页 paginator.num_pages < 5

如果总页数大于5页 当前页数属于前3页 page <=3

如果总页数大于5页 当前页数属于最后3页 paginator.num_pages - page <3

代码语言:javascript复制
class ListView(BaseCartView):
    """商品列表页面"""
    def get(self, request, category_id, page):
        # 商品类别 顺序  页数
        sort = request.GET.get("sort", "default")

        if sort not in ("price", "hot"):
            sort = "default"

        # 校验参数
        # 判断类别是否存在
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            # 类别不存在
            return redirect(reverse("goods:index"))

        # 根据参数 查询数据库
        # 购物车数量
        cart_num = self.get_cart_num(request)

        # 分类信息
        categorys = GoodsCategory.objects.all()

        # 分类的新品推荐
        new_skus = GoodsSKU.objects.filter(category=category).order_by("-create_time")[:2]

        # 分类的商品, 排序
        if sort == "price":
            skus = GoodsSKU.objects.filter(category=category).order_by("price")
        elif sort == "hot":
            skus = GoodsSKU.objects.filter(category=category).order_by("-sales")
        else:
            skus = GoodsSKU.objects.filter(category=category)

        # 分页
        paginator = Paginator(skus, 1)

        page = int(page)
        try:
            page_skus = paginator.page(page)
        except EmptyPage:
            # 表示用户请求的页数不存在
            page_skus = paginator.page(1)
            page = 1

        # 页数
        # 如果总页数小于5页  paginator.num_pages < 5
        # 如果总页数大于5页  当前页数属于前3页 page <=3
        # 如果总页数大于5页  当前页数属于最后3页  paginator.num_pages - page <3
        # 其他
        num_pages = paginator.num_pages  # 总页数
        if num_pages < 5:
            # 如果总页数小于5页  paginator.num_pages < 5
            page_list = range(1, num_pages 1)
        elif page <= 3:
            # 如果总页数大于5页  当前页数属于前3页 page <=3
            page_list = range(1, 6)  # [1,2,3,4,5]
        elif paginator.num_pages - page < 3:
            # 如果总页数大于5页  当前页数属于最后3页  paginator.num_pages - page <3
            page_list = range(num_pages-4, num_pages 1)
        else:
            page_list = range(page-2, page 3)

        # 处理模板
        context = {
            "category": category,
            "categorys": categorys,
            "new_skus": new_skus,
            "page_skus": page_skus,
            "page_list": page_list,  # 页码
            "sort": sort,
            "cart_num": cart_num
        }

        return render(request, "list.html", context)

0 人点赞