You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django实现非主键的客户订单号自动递增方案

解决Django中客户订单order_number按客户自动递增的问题

需求

实现每个客户提交的订单的order_number字段自动递增,且不修改Order模型的主键(primary_key)。

现有代码

Models.py

class Customer(models.Model):
    customer_name = models.CharField(max_length=100)
    customerID = models.CharField(max_length=100)

class Order(models.Model):
    customer = models.ForeignKey(Customer, related_name='order', on_delete=models.CASCADE)
    order_name = models.CharField(max_length=100)
    order_number = models.IntegerField(default=0)

Serializers.py

from rest_framework import serializers
from .models import *


class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = '__all__'

class CustomerSerializer(serializers.ModelSerializer):
    orders = OrderSerializer(many=True, read_only=True, required=False)

    class Meta:
        model = Customer
        fields = '__all__'

views.py

from rest_framework import generics, status
from rest_framework.views import APIView
from rest_framework.response import Response
from django.shortcuts import get_object_or_404

from .models import *
from .serializers import *

class CustomerListView(generics.ListCreateAPIView):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

class CustomerDetailView(generics.RetrieveDestroyAPIView):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

class OrderListView(generics.ListCreateAPIView):
    def get_queryset(self):
        queryset = Order.objects.filter(customer_id=self.kwargs["pk"])
        return queryset
    serializer_class = OrderSerializer

class OrderDetailView(generics.RetrieveDestroyAPIView):
    serializer_class = OrderSerializer 

    def get_queryset(self):
        queryset = Order.objects.filter(id=self.kwargs["pk"])
        return queryset

urls.py

from django.urls import path

from .views import *

urlpatterns = [
    path('', CustomerListView.as_view(), name=''),    
    path('<int:pk>/', CustomerDetailView.as_view(), name=''),    
    path('<int:pk>/orders/', OrderListView.as_view(), name=''),    
    path('<int:customer_pk>/orders/<int:pk>/', OrderDetailView.as_view(), name=''),    
]

期望返回示例

[    
    {
        "id": 1,
        "order": [
            {
                "id": 1,
                "order_name": "fruit",
                "order_number": 1,
                "customer": 1
            },
            {
                "id": 2,
                "order_name": "chair",
                "order_number": 2,
                "customer": 1
            },
            {
                "id": 3,
                "order_name": "pc",
                "order_number": 3,
                "customer": 1
            }
        ],
        "customer_name": "john doe",
        "customerID": "81498"
    },
    {
        "id": 2,
        "order": [
            {
                "id": 4,
                "order_name": "phone",
                "order_number": 1,
                "customer": 2
            },
            {
                "id": 5,
                "order_name": "car",
                "order_number": 2,
                "customer": 2
            }
        ],
        "customer_name": "jane doe",
        "customerID": "81499"
    }
]

解决方案

要实现按客户单独递增order_number,只需在Order模型中重写save方法,针对当前客户的已有订单计算编号:

修改后的Models.py代码

from django.db import models

class Customer(models.Model):
    customer_name = models.CharField(max_length=100)
    customerID = models.CharField(max_length=100)

class Order(models.Model):
    customer = models.ForeignKey(Customer, related_name='order', on_delete=models.CASCADE)
    order_name = models.CharField(max_length=100)
    order_number = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        # 仅在新建订单时自动生成编号
        if not self.pk:
            # 获取当前客户已有的最大order_number
            last_num = Order.objects.filter(customer=self.customer).aggregate(largest=models.Max('order_number'))['largest']
            # 无订单则从1开始,否则递增
            self.order_number = last_num + 1 if last_num is not None else 1
        super().save(*args, **kwargs)

关键修改说明

原方案中若使用全局获取最大编号的逻辑(last_id = self.objects.all().aggregate(largest=models.Max('display_id'))['largest']),会导致所有客户的订单编号连续递增,无法实现按客户独立计数。我们需要将其修改为针对当前客户过滤订单,只计算该客户的最大order_number:

last_num = Order.objects.filter(customer=self.customer).aggregate(largest=models.Max('order_number'))['largest']

修改后,每次为客户创建新订单时,系统会自动生成该客户专属的递增编号,完全符合需求。

内容的提问来源于stack exchange,提问作者mRezaAnanta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 01:36:00