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
相关产品推荐
相关产品推荐

