【问题标题】:Django models for creating multiple variations of t-shirts用于创建多种 T 恤衫的 Django 模型
【发布时间】:2021-11-10 21:58:21
【问题描述】:

我正在创建一家电子商务商店,销售 T 恤、连帽衫、马克杯、小酒杯等。对于 T 恤和连帽衫,每种产品都有尺寸,有时还有颜色。我正在尝试为每种产品添加多种变体。这是我的 model.py 代码:

class Category(models.Model):
    name = models.CharField(max_length = 255, db_index=True, null=True, blank=True)
    slug = models.SlugField(max_length=255, unique=True, default='')
    class Meta:
        verbose_name_plural = 'categories'

    def get_absolute_url(self):
        return reverse('main:category_list', args=[self.slug])
    def __str__(self):
        return self.name

class Product(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)
    name = models.CharField(max_length = 255, default='')
    description = models.TextField(blank=True)
    image = models.ImageField(upload_to='products/', null=True, blank=True)
    slug = models.SlugField(max_length = 255, default='')
    price = models.DecimalField(max_digits=4,decimal_places=2)
    update_defaults = models.BooleanField(default=False)
    #inventory = models.DecimalField(max_digits=5, decimal_places=None)

    class Meta:
        ordering=(['name'])

    def get_absolute_url(self):
        return reverse('main:product_detail', args=[self.slug])

    def __str__(self):
        return self.name

class VariationManager(models.Manager):
    def all(self):
        return super(VariationManager, self).filter(active=True)

    def sizes(self):
        return self.all().filter(category='size')

    def colors(self):
        return self.all().filter(category='color')


VAR_CATEGORIES = (
    ('size', 'size'),
    ('color', 'color'),
    )


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=100, decimal_places=2, null=True, blank=True)
    updated = models.DateTimeField(auto_now_add=False, auto_now=True)
    active = models.BooleanField(default=True)

    objects = VariationManager()

    def __str__(self):
        return self.category + " " + self.title

def product_defaults(sender, instance, created, *args, **kwargs):
    if instance.update_defaults:
        categories = Category.objects.all()
        print (categories)
        for cat in categories:
            print (cat.id)
            if cat.id == 1: #for t-shirts
                small_size = Variation.objects.get_or_create(product=instance,
                                            category='size',
                                            title='Small')
                medium_size = Variation.objects.get_or_create(product=instance,
                                            category='size',
                                            title='Medium')
                large_size = Variation.objects.get_or_create(product=instance,
                                            category='size',
                                            title='Large')
                XL_size = Variation.objects.get_or_create(product=instance,
                                            category='size',
                                            title='XL')
                DoubleXL_size = Variation.objects.get_or_create(product=instance,
                                            category='size',
                                            title='2XL')
                TripleXL_size = Variation.objects.get_or_create(product=instance,
                                            category='size',
                                            title='3XL')
        instance.update_defaults = False
        instance.save()

post_save.connect(product_defaults, sender=Product)

它现在在我的管理界面中的显示方式是名称、属性、值和价格(为清楚起见,仅命名相关字段)。如果我添加这样的产品:“t-shirt_1, size, sm, 17.98”,那么我需要添加的下一个项目是“t-shirt_1, size, med, 17.98”等等(2xl 及以上,价格上涨向上)。有没有办法简化这一点,我只需输入产品名称一次,然后为产品中的每个尺寸添加所有尺寸和相关定价,以及库存跟踪(尚未创建字段)?

编辑: 我已经编辑了我的代码。我弄明白了变化。现在我不知道如何将库存数量与它联系起来。如果我把它放在产品类中,它没有指定什么尺寸(即 10 小、8 中、12 大)。

【问题讨论】:

    标签: django model e-commerce


    【解决方案1】:

    Product模型中移除对应的属性字段,并在ProductProductAttribute之间建立OneToMany关系。然后创建单独的 Size 和 Color 模型,并将它们与 ProductAttributeManyToMany 关系相关联:

    class Product(models.Model):
        category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)
        name = models.CharField(max_length = 255, default='')
        description = models.TextField(blank=True)
        image = models.ImageField(upload_to='products/', null=True, blank=True)
        slug = models.SlugField(max_length = 255, default='')
        price = models.DecimalField(max_digits=4,decimal_places=2)
        has_attributes = models.BooleanField(default=False)
        ...
    
    
    class ProductAttribute(models.Model):
        product = models.ForeignKey('Product', related_name="product_attrs", on_delete=models.CASCADE)
        sizes = models.ManyToManyField('Size', related_name="product_sizes", null=True, blank=True)
        colors = models.ManyToManyField('Product', related_name="product_colors", null=True, blank=True)
        ...
    
    
    class Size(models.Model):
        size_num = models.CharField(max_length=10)
        ...
    
    
    class Color(models.Model):
        color_name = models.CharField(max_length=15)
        ...
    

    现在您可以创建Product 对象,然后转到ProductAttribute 将相应的产品对象与产品属性模型相关联,并添加该产品的每个属性(尺寸或颜色)。每当您需要获取产品尺寸或颜色时,您都可以按以下方式进行:

    # let's say you need to get sizes of last product
    p = Product.objects.last()
    sizes = p.product_attrs.sizes.all()
    # ↑ returns queryset containing all sizes of product
    

    【讨论】:

    • 感谢您的帮助。它并没有像预期的那样工作。 size = p.product_attrs.sizes.all() 不起作用,因为 Product 没有名为“sizes”的字段。我将您的解决方案修改为可行的解决方案,但现在我遇到了另一个问题。我摆脱了中间的 ProductAttributes 类,并为颜色和尺寸创建了单独的类,并将它们作为字段添加到产品中,但是如何将剩余数量和与每个产品相关的每个变体的价格关联起来?
    • 如果你做的一切都正确,p.product_attrs 应该返回 ProductAttribute 对象而不是 Product。
    • 谢谢。我得到了它。对检索查询集稍作修改。而不是 p.product_attrs.sizes.all() 它只是 p.product_attrs.all() 因为 Product 类中没有“大小”。我仍然不确定在哪里或如何存储库存数量。如果我把它放在产品中,那将是什么数量?小的?中等的?等等。如果我按尺码或颜色存储,如果不是 T 恤怎么办?
    • 我已经修改了我的整个代码。我什至有一个函数可以用默认大小填充所有内容。贴在新代码上面。将库存数量与产品变体联系起来的可能想法。
    • 我鼓励你打开一个新线程并在那里解释你的问题,因为你并没有真正使用我的方式
    【解决方案2】:

    不需要

    class Attribute(models.Model):
        name = models.CharField(max_length = 255,   default='')
    
        def __str__(self):
            return self.name
    

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-07
    • 2020-07-27
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    相关资源
    最近更新 更多