前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django实战-生鲜电商-用户地址|订单确认

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

作者头像
小团子
发布2019-07-18 16:06:07
6180
发布2019-07-18 16:06:07
举报
文章被收录于专栏:数据云团

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

一、用户地址

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

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

代码语言:javascript
复制
class LoginRequiredMixin(object):
    """验证用户的登录状态"""
    @classmethod
    def as_view(cls, **initkwargs):
        view = super(LoginRequiredMixin, cls).as_view(**initkwargs)
        return login_required(view)
代码语言:javascript
复制
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"))

二、订单确认

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

代码语言:javascript
复制
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)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据云团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档