专栏首页数据云团Django实战-生鲜电商-用户中心|商品详情

Django实战-生鲜电商-用户中心|商品详情

完成了项目的模型层,最需要思考的是数据库该如何设计?这次的电商项目,从用户到下单,都会有哪些操作呢?当看到页面的那些商品信息或是活动促销信息,有考虑过它们之间的联系么?要是,商品的分类要像某宝或是某东,那样有二级和三级分类,这样又该怎么处理呢?如果每个功能的数据表都单独设计成和用户关联,那功能的不断扩展,会不会影响到整个数据库读写与查询呢?

完成了前一小节的主页,需要对商品详情页单独写一个视图类。会发现,在主页的视图和商品详情页视图中,都会先从缓存中去查询有无数据。

一、商品详情页

from django_redis import get_redis_connection

django_redis 在 settings.py 文件中配置

# 缓存
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/5",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}
class DetailView(BaseCartView):
    """商品详细信息页面"""
    def get(self, request, sku_id):
        # 尝试获取缓存数据
        context = cache.get("detail_%s" % sku_id)
        # 如果缓存不存在
        if context is None:
            try:
                # 获取商品信息
                sku = GoodsSKU.objects.get(id=sku_id)
            except GoodsSKU.DoesNotExist:
                # from django.http import Http404
                # raise Http404("商品不存在!")
                return redirect(reverse("goods:index"))

            # 获取类别
            categorys = GoodsCategory.objects.all()

            # 从订单中获取评论信息
            sku_orders = sku.ordergoods_set.all().order_by('-create_time')[:30]
            if sku_orders:
                for sku_order in sku_orders:
                    sku_order.ctime = sku_order.create_time.strftime('%Y-%m-%d %H:%M:%S')
                    sku_order.username = sku_order.order.user.username
            else:
                sku_orders = []

            # 获取最新推荐
            new_skus = GoodsSKU.objects.filter(category=sku.category).order_by("-create_time")[:2]

            # 获取其他规格的商品
            goods_skus = sku.goods.goodssku_set.exclude(id=sku_id)

            context = {
                "categorys": categorys,
                "sku": sku,
                "orders": sku_orders,
                "new_skus": new_skus,
                "goods_skus": goods_skus
            }

            # 设置缓存
            cache.set("detail_%s" % sku_id, context, 3600)

        # 购物车数量
        cart_num = self.get_cart_num(request)

        # 浏览记录
        # 如果是登录的用户
        if request.user.is_authenticated():
            redis_conn = get_redis_connection("default")
            user_id = request.user.id
            # 移除已经存在的本商品浏览记录
            redis_conn.lrem("history_%s" % user_id, 0, sku_id)
            # 添加新的浏览记录
            redis_conn.lpush("history_%s" % user_id, sku_id)
            # 只保存最多5条记录
            redis_conn.ltrim("history_%s" % user_id, 0, 4)

        context.update({"cart_num": cart_num})

        return render(request, 'detail.html', context)

二、用户中心

在用户进入个人中心之前都需要先验证用户是否登录,在很多地方都会需要用到登录验证,比如下单、支付、填写地址。所以最好将验证登录作为一个可继承的 mixin 类,这样在其它需要登录验证的视图中就可以直接继承。

① 验证用户的登录状态

class LoginRequiredMixin(object):
    """验证用户的登录状态"""
    @classmethod
    def as_view(cls, **initkwargs):
        view = super(LoginRequiredMixin, cls).as_view(**initkwargs)
        return login_required(view)

② 用户中心

class UserInfoView(LoginRequiredMixin, View):
    """用户中心"""
    def get(self, request):
        user = request.user

        try:
            address = user.address_set.latest("create_time")
        except Address.DoesNotExist:
            # 如果地址信息不存在
            address = None

        # 从django_redis中拿到一个与redis的连接对象
        redis_conn = get_redis_connection("default")

        # 从redis中查询用户的历史记录信息
        sku_ids = redis_conn.lrange("history_%s" % user.id, 0, 4)

        # sku_ids = [5,6,3,9,1]

        # 从数据库中查询商品的信息
        # select * from goods_sku where id in ()
        # skus = GoodsSKU.objects.filter(id__in=sku_ids)

        skus = []
        for sku_id in sku_ids:  # [5,6,3,9,1]
            sku = GoodsSKU.objects.get(id=sku_id)
            skus.append(sku)

        # 形成模板所用的变量,渲染模板
        context = {
            "address": address,
            "skus": skus   # [5,6,3,9,1]
        }
        return render(request, "user_center_info.html", context)

本文分享自微信公众号 - 数据云团(SmartData)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 十二要素

    一份基准代码(Codebase),多份部署(deploy) 尽管每个应用只对应一份基准代码,但可以同时存在多份部署。每份 部署 相当于运行了一个应用的实例。

    分母为零
  • 详述一次大量删除导致MySQL慢查的过程分析

    原文:http://www.enmotech.com/web/detail/1/740/1.html

    数据和云01
  • 漫谈“数据湖”

    数据湖这一概念,最早是在2011年由CITO Research网站的CTO和作家Dan Woods首次提出。其比喻是:如果我们把数据比作大自然的水,那么各个江川...

    宜信技术学院
  • 【数据库】MySQL查询优化

    在这个快速发展的时代,时间变得 越来越重要,也流逝得非常得快,有些人长大了,有些人却变老了。稍不留神,2019已经过完了三分之一。回首这四个月收获什么,懂得了什...

    用户3467126
  • 5、web爬虫,scrapy模块,解决重复ur——自动递归url

    一般抓取过的url不重复抓取,那么就需要记录url,判断当前URL如果在记录里说明已经抓取过了,如果不存在说明没抓取过

    天降攻城狮
  • 在同一个workprocess里对两张表分别使用online update和update function module update

    用一个report测试,表1是直接online update,表2在update function module里update,由于有了SET UPDATE T...

    Jerry Wang
  • nacos部署使用mysql作为数据库

    Nacos是阿里巴巴开源的一款支持服务注册与发现,配置管理以及微服务管理的组件,这里我不讲nacos的docker部署,没错,如果你使用官方的方式部署nacos...

    bboysoul
  • 2019年7月数据库流行度排行:Oracle王者归来获大幅增长

    原文:http://www.enmotech.com/web/detail/1/736/1.html   

    数据和云01
  • cicd-wayne-1:kubernetes中容器化wayne

    git clone https://github.com/Qihoo360/wayne.git

    千里行走
  • 【数据库】MySQL锁机制、热备、分表

    加锁的方式:自动加锁。查询操作(SELECT),会自动给涉及的所有表加读锁,更新操作(UPDATE、DELETE、INSERT),会自动给涉及的表加写锁。

    用户3467126

扫码关注云+社区

领取腾讯云代金券