前面一小节完成了对登录、注册、激活的视图,需要注意的是,在逻辑处理上需要明确是采用何种方式实现浏览器的登录状态保存。
一、主页视图
在主页视图中,有用到缓存机制
- 商品分类信息
- 首页轮播图信息
- 活动信息
- 提供购物车数据统计功能
① 提供购物车数据统计功能
代码语言: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)