开源web框架django知识总结(二十)

本文总结了开源web框架Django中订单系统的实现,包括从结算订单逻辑分析,新建订单数据库表,使用事务保存订单数据,解决并发下单问题,到展示提交订单成功页面的全过程。详细介绍了Django事务的使用,乐观锁在并发控制中的应用,以及订单数据的持久化处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开源web框架django知识总结(二十)

阿尔法商城(订单)

订单

提示:

  • 订单入口 在《购物车》页面的《去结算》。
  • 《去结算》后进入到《结算订单》页面,展示出要结算的商品信息。

结算订单

在这里插入图片描述

新建apps->orders,同步数据,注册app,新建子路由urls.py,添加项目主路由

1. 结算订单逻辑分析

结算订单是从Redis购物车中查询出被勾选的商品信息进行结算并展示。

2. 结算订单接口设计和定义

1.请求方式

选项 方案
请求方法 GET
请求地址 /orders/settlement/

**2.请求参数:**无

3.响应结果:HTML place_order.html

4.后端接口定义

class OrderSettlementView(LoginRequiredMixin, View):
    """结算订单"""
 
    def get(self, request):
        """提供订单结算页面"""
       pass
  1. 结算订单后端逻辑实现
from django.views import View
from django_redis import get_redis_connection
from goods.models import SKU
from users.models import Address
from django.http import JsonResponse
# Paginator:分页器
from decimal import Decimal  # 数据精确处理
from aerf_mall.utils.views import login_required
from django.utils.decorators import method_decorator


class OrderSettlementView(View):

    @method_decorator(login_required)
    def get(self, request):
        user = request.user
        # 1、读取用户购物商品(必须是选中的!)
        conn = get_redis_connection('carts')
        # {b'1': b'4'}  hgetall,返回所有的字段和值。
        cart_redis = conn.hgetall('carts_%s'%user.id)
        # [b'1'] smembers返回所有集合
        cart_selected = conn.smembers('selected_%s'%user.id)

        # 构造商品返回数据
        sku_list = []
        for k,v in cart_redis.items():
            # k:b'1'; v:b'4'
            if k in cart_selected:
                sku = SKU.objects.get(pk=k)
                sku_list.append({
   
                    'id': sku.id,
                    'name': sku.name,
                    'default_image_url': sku.default_image_url.url,
                    'price': sku.price,
                    'count': int(v)
                })

        # 2、读取用户的收货地址数据
        addresss_list = []
        addresses = Address.objects.filter(user=user)
        for address in addresses:
            if not address.is_deleted:
                addresss_list.append({
   
                      "id": address.id,
                      "province": address.province.name,
                      "city": address.city.name,
                      "district": address.district.name,
                      "place": address.place,
                      "mobile": address.mobile,
                      "receiver": address.receiver,
                })

        # 3、构建响应数据
        # freight = 10.0
        # 结论:使用Decimal类型来保存十进制数,目的是为了保证计算的精确度,Decimal(10,5)10位数,其中小数占5位
        freight = Decimal('10.5')

        return JsonResponse({
   
            'code': 0,
            'errmsg': 'ok',
            'context': {
   
                'addresses': addresss_list,
                'skus': sku_list,
                'freight': freight
            }
        })

=======================================

提交订单

提示:

  • 确认了要结算的商品信息后,就可以去提交订单了。

创建订单数据库表

生成的订单数据要做持久化处理,而且需要在《我的订单》页面展示出来。

1. 订单数据库表分析

注意:

  • 订单号不再采用数据库自增主键,而是由后端生成。
  • 一个订单中可以有多个商品信息,订单基本信息和订单商品信息是一对多的关系。
    在这里插入图片描述

2. 订单模型类、迁移、建表

orders.models.py

from django.db import models
from aerf_mall.utils.BaseModel import BaseModel
from users.models import User,Address
from goods.models import SKU
# Create your models here.

# 
class OrderInfo(BaseModel):
    """订单信息"""
    PAY_METHODS_ENUM = {
   
        "CASH": 1,
        "ALIPAY": 2
    }
    PAY_METHOD_CHOICES = (
        (1, "货到付款"),
        (2, "支付宝"),
    )
    ORDER_STATUS_ENUM = {
   
        "UNPAID": 1,
        "UNSEND": 2,
        "UNRECEIVED": 3,
        "UNCOMMENT": 4,
        "FINISHED": 5
    }
    ORDER_STATUS_CHOICES = (
        (1, "待支付"),
        (2, "待发货"),
        (3, "待收货"),
        (4, "待评价"),
        (5, "已完成"),
        (6, "已取消"),
    )

    # primary_key=True表明当前字段作为主键——自定义主键
    order_id = models.CharField(max_length=64, primary_key=True, verbose_name="订单号")
    user = models.ForeignKey(User, on_delete=models.PROTECT, verbose_name="下单用户")
    address = models.ForeignKey(Address, on_delete=models.PROTECT, verbose_name="收货地址")
    total_count = models.IntegerField(default=1, verbose_name="商品总数")

    # DecimalField类型字段:十进制的数(高精度)
    total_amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="商品总金额")
    freight = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="运费")

    pay_method = models.SmallIntegerField(choices=PAY_METHOD_CHOICES, default=1, verbose_name="支付方式")
    status = models.SmallIntegerField(choices=ORDER_STATUS_CHOICES, default=1, verbose_name="订单状态")

    class Meta:
        db_table = "tb_order_info"
        verbose_name = '订单基本信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.order_id

# 
class OrderGoods(BaseModel):
    """订单商品"""
    SCORE_CHOICES = (
        (0, '0分'),
        (1, '20分'),
        (2, '40分'),
        (3, '60分'),
        (4, '80分'),
        (5, '100分'),
    )
    order = models.ForeignKey(OrderInfo, related_name='skus', on_delete=models.CASCADE, verbose_name="订单")
    sku = models.ForeignKey(SKU, on_delete=models.PROTECT, verbose_name="订单商品")
    count = models.IntegerField(default=1, verbose_name="数量")
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="单价")
    comment = models.TextField(default="", verbose_name="评价信息")
    score 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

主打Python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值