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

Django电商站点T恤等商品多规格模型实现及库存绑定问题

方案实现

1. 多规格库存关联

你当前的库存不能放在Product表,因为每个规格的库存是独立的,根据你的业务场景可以选择两种方案:

方案A:单属性区分规格(无需组合尺寸+颜色)

直接在Variation模型中添加库存字段即可,修改你的models.py中Variation类:

class Variation(models.Model):
    product = models.ForeignKey(Product, related_name="product_attrs", on_delete=models.CASCADE)
    category = models.CharField(max_length=120, choices=VAR_CATEGORIES, default='size')
    title = models.CharField(max_length=120)
    price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) # 注意max_digits不要设100,过度占用存储空间,10足够覆盖常规定价
    inventory = models.IntegerField(default=0, verbose_name="库存数量") # 新增库存字段
    updated = models.DateTimeField(auto_now_add=False, auto_now=True)
    active = models.BooleanField(default=True)

    objects = VariationManager()

    def __str__(self):
        return f"{self.category}:{self.title}"

这种方案适合商品只用一个属性区分的场景,比如T恤只有尺寸区分、马克杯只有颜色区分,每个Variation直接对应一个可售卖的单元,库存和价格都存在这里,完美实现小码10件、中码8件这类独立库存的需求。

方案B:多属性组合规格(需要同时选尺寸+颜色)

如果你的商品需要多个属性组合区分(比如红色M码T恤、蓝色L码T恤是两个独立售卖单元,各有各的库存价格),需要新增SKU模型:

class Sku(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="skus", verbose_name="所属商品")
    attrs = models.ManyToManyField(Variation, verbose_name="关联规格")
    price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="售价")
    inventory = models.IntegerField(default=0, verbose_name="库存数量")
    active = models.BooleanField(default=True, verbose_name="是否上架")
    sku_code = models.CharField(max_length=64, unique=True, blank=True, null=True, verbose_name="SKU编码")

    def __str__(self):
        attr_str = " ".join([str(v) for v in self.attrs.all()])
        return f"{self.product.name} {attr_str}"

    def save(self, *args, **kwargs):
        # 可选:自动生成SKU编码,不需要可以删掉这段逻辑
        if not self.sku_code:
            attr_ids = sorted([v.id for v in self.attrs.all()])
            self.sku_code = f"P{self.product.id}A{''.join(map(str, attr_ids))}"
        super().save(*args, **kwargs)

这种方案下价格和库存统一存在SKU表,原来Variation的price字段可以删除,避免数据冲突。

2. Admin录入简化

用Django自带的内联表单(Inline)就能实现同一个商品编辑页批量录入所有规格信息,无需单独跳转添加每条规格:
在你的admin.py中添加如下配置:

对应方案A的配置

from django.contrib import admin
from .models import Category, Product, Variation

class VariationInline(admin.TabularInline):
    model = Variation
    extra = 0 # 新建商品时默认的空规格行数,你也可以根据分类默认设置对应数量
    fields = ["category", "title", "price", "inventory", "active"]

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ["name", "category", "price"]
    inlines = [VariationInline] # 把规格表单内嵌到商品编辑页

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("name",)} # 自动生成slug,可选配置

配合你原来的自动生成默认尺寸的信号,新建T恤类商品时会自动创建好所有尺寸的Variation行,你直接填价格和库存即可,无需手动添加每个规格。

对应方案B的配置

from django.contrib import admin
from .models import Category, Product, Variation, Sku

class SkuInline(admin.TabularInline):
    model = Sku
    extra = 0
    fields = ["attrs", "price", "inventory", "active"]

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ["name", "category", "price"]
    inlines = [SkuInline]

# 其他模型的admin配置按需添加

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 20:15:03