专栏首页数据云团Django实战-生鲜电商-用户地址|订单确认

Django实战-生鲜电商-用户地址|订单确认

在完成登录到用户提交订单,这一系列的类视图函数,会发现有大量的数据读写操作,像电商这类的项目,更多的是用户在浏览页面的次数比较多,所以在数据查询的场景中都会采用缓存,将用户第一次打开页面,到下一次重新浏览,这其间就可以提升用户打开页面的速度。

一、用户地址

用户地址的类视图,包括用户查询地址,也可以让用户创建新的收货地址。

在进入该视图之前,需要先验证用户是否登录,继承 LoginRequiredMinxin 类。

class LoginRequiredMixin(object):
    """验证用户的登录状态"""
    @classmethod
    def as_view(cls, **initkwargs):
        view = super(LoginRequiredMixin, cls).as_view(**initkwargs)
        return login_required(view)
class AddressView(LoginRequiredMixin, View):
    """用户地址"""
    def get(self, request):
        # 获取登录的用户
        user = request.user

        # 获取地址信息
        #
        # Address.objects.filter(user=user).order_by("create_time")[0]
        #
        # user.address_set.order_by("create_time")[0]
        #
        try:
            address = user.address_set.latest("create_time")
        except Address.DoesNotExist:
            # 如果地址信息不存在
            address = None

        context = {
            # "user": user,  # django的模板中可以直接使用user模板变量
            "address": address
        }

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

    def post(self, request):
        """修改地址信息"""
        user = request.user
        recv_name = request.POST.get("recv_name")
        addr = request.POST.get("addr")
        zip_code = request.POST.get("zip_code")
        recv_mobile = request.POST.get("recv_mobile")

        if all([recv_name, addr, zip_code, recv_mobile]):
            # address = Address(
            #     user=user,
            #     receiver_name=recv_name,
            #     detail_addr=addr,
            #     zip_code=zip_code,
            #     receiver_mobile=recv_mobile
            # )
            # address.save()
            Address.objects.create(
                user=user,
                receiver_name=recv_name,
                detail_addr=addr,
                zip_code=zip_code,
                receiver_mobile=recv_mobile
            )
        return redirect(reverse("users:address"))

二、订单确认

下单前需要得到用户购买的是哪件商品以及购买的数量;再计算出商品的价格和库存数量。

class PlaceOrderView(LoginRequiredMixin, View):
    """订单确认页面"""
    def post(self, request):
        # 获取参数
        sku_ids = request.POST.getlist("sku_ids")  #  要购买的商品id  [1,2,3,4,5]
        count = request.POST.get("count")  # 商品的数量,从商品详情页面进入这个视图时需要传递,从购物车页面进入这个视图时不需要传递
                                           # 商品详情页面的商品只有一个,所以数量也只有一个

        # 校验参数
        if not sku_ids:
            # 跳转到购物车页面
            return redirect(reverse("cart:info"))

        redis_conn = get_redis_connection("default")
        user_id = request.user.id

        skus = []
        total_count = 0
        total_skus_amount = 0
        trans_cost = 10  # 邮费,暂时写死

        # 查询商品数据
        if count is None:
            # 如果是从购物车页面过来,商品的数量需要从redis中获取
            cart = redis_conn.hgetall("cart_%s" % user_id)
            total_amount = 0  # 包含了邮费和商品总金额的数值
            # 遍历商品id,获取商品信息
            for sku_id in sku_ids:
                try:
                    sku = GoodsSKU.objects.get(id=sku_id)
                except GoodsSKU.DoesNotExist:
                    # 跳转到购物车页面
                    return redirect(reverse("cart:info"))
                # 读取商品的数量
                sku_count = cart.get(sku_id.encode())
                sku_count = int(sku_count)

                # 计算商品的金额
                amount = sku.price * sku_count
                sku.amount = amount
                sku.count = sku_count
                skus.append(sku)
                total_count += sku_count
                total_skus_amount += amount
        else:
            # 如果是从商品详情页面过来,商品的数量直接就是count参数值
            for sku_id in sku_ids:
                try:
                    sku = GoodsSKU.objects.get(id=sku_id)
                except GoodsSKU.DoesNotExist:
                    # 跳转到购物车页面
                    return redirect(reverse("cart:info"))

                try:
                    sku_count = int(count)
                except Exception:
                    # 跳回到商品的详情页面
                    return redirect(reverse("goods:detail", args=(sku_id,)))

                # 判断库存
                if sku_count > sku.stock:
                    # 跳回到商品的详情页面
                    return redirect(reverse("goods:detail", args=(sku_id,)))

                # 计算商品的金额
                amount = sku.price * sku_count
                sku.amount = amount
                sku.count = sku_count
                skus.append(sku)
                total_count += sku_count
                total_skus_amount += amount

                # 将商品存放到购物车中
                redis_conn.hset("cart_%s" % user_id, sku_id, sku_count)

        total_amount = total_skus_amount + trans_cost

        # 地址信息
        # address = Address.objects.filter(user_id=user_id)
        try:
            address = Address.objects.filter(user=request.user).latest("create_time")
        except Address.DoesNotExist:
            address = None

        # 返回前端页面
        context = {
            "skus": skus,
            "total_count": total_count,
            "total_skus_amount": total_skus_amount,
            "total_amount": total_amount,
            "trans_cost": trans_cost,
            "address": address,
            "sku_ids": ",".join(sku_ids)
        }
        return render(request, "place_order.html", context)

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

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

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

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 6、web爬虫讲解2—urllib库爬虫—基础使用—超时设置—自动模拟http请求

    urlretrieve()将网络文件下载保存到本地,参数1网络文件URL,参数2保存路径

    天降攻城狮
  • 用了几年 Python,但你可能连这个都没学透

    在 Python 中用的最多的可能就是 import 了,几乎我们写的每个 Python 脚本都是需要的,但这个 import 其实也有些讲究的,比如用不好很可...

    崔庆才
  • Python 高效编程技巧

    Python 提供了几个高级内置函数,另外还有几个比较实用的库,比如 collections,这里推荐一篇文章,介绍几个小的 Tips,如果大家用上的话可以稍微...

    崔庆才
  • Python开发-九层之台 起于垒土

    Python3.7 安装目录 D:\Program Files\python37

    needrunning
  • 这么多编程语言到底都是干啥的 看完这个你就懂

    TIOBE排行榜每个月都会发布编程语言排行,在榜单中编程语言们上上下下,有的牢牢把握前三,有的忽上忽下,有的被挤出前20,过会又杀了回来。外行只看到语言的起起伏...

    用户5745563
  • 《SparkSql使用教程》--- 大数据系列

    在Spark中,DataFrame是一种以RDD为基础的分布式数据据集,类似于传统数据库听二维表格,DataFrame带有Schema元信息,即...

    用户3467126
  • 这样自学 Python ,高效不止一点,两点

    经过这些年的自学编程,来跟你谈谈我是怎么自学的,给你做点参考,当然,如果你也有不错的自学方法或者经验,我们可以彼此探讨,借鉴一下,也许大家都能同时进步一点点。

    一墨编程学习
  • 关于字符串处理,你真的全掌握了吗?

    字符串处理是 Python 中最基本的操作之一了,但其实有些用法你真的可能没有注意到,这里分享一篇关于 Python 字符串处理的总结文章,希望对大家有帮助。

    崔庆才
  • Leetcode【54、59、885】

    这道题做法很直接,就是从最外层到最内层一层一层按照顺时针螺旋输出各个数字即可。如下图所示:

    echobingo
  • Python安装麻烦?试试Google推出的colab

    刚开始用Python的时候,总会在安装Python环境中遇到不少问题。比如说,安装之后怎么使用,新的package怎么安装等。今天发现了一款解决这些入门问题的黑...

    宋彦

扫码关注云+社区

领取腾讯云代金券