从另一个表填充默认值

时间:2011-05-05 02:41:59

标签: django django-models django-admin

这里有点不知所措。基本上我在管理部分有一个产品页面,在底部我有一个TabularInline,让我选择产品的尺寸并设定价格。这有效,但我试图得到它,以便它从Sizes表中拉出默认价格作为初始值。

我尝试了以下内容:

class Size(models.Model):
    name = models.CharField(max_length=50)
    default_price = models.DecimalField(max_digits=9, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'sizes'
        ordering = ['-created_at']
        verbose_name_plural = 'Sizes'

    def __unicode__(self):
        return self.name

    def default_price(self):
        return self.default_price

然后

class ProductOption(models.Model):
    product = models.ForeignKey(Product)
    size = models.ForeignKey(Size)
    price = models.DecimalField(max_digits=9, decimal_places=2, default=Size.default_price)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now_add=True)

验证,但是当我加载管理页面时,我得到以下内容:

未绑定方法get_default_price()必须使用Size实例作为第一个参数调用(没有任何内容)

不确定从这里可以去哪里。我一直在寻找Django文档,试图找到别的东西来尝试。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

所以,你可以覆盖save方法,如果没有self.id,你可以先填充其他一些字段,这就是最好的解决方案。

仅举例:

def save(*args, **kwargs):
    if not self.id:
        self.size = SomeOtherModel.objects.get(pk=size)

    super(Size, self).save(*args, **kwargs)

答案 1 :(得分:0)

这里有几个问题:

Size.default_price是一个可调用对象,因此python在设置ProductOption的默认值时会尝试调用它。您可能正在寻找的是:

class Size(models.Model):
    # Other stuff here
    @property
    def default_price(self):
        return self.default_price

然而,这会导致另一个更深层的错误。如果您有以下内容:

size = Size()
size.default_price

由于无限递归,您最终会收到StackOverflow。这个属性称自己。解决方案是使属性名称与属性不同,或者在这种最简单的情况下,它已经有点像属性。您只需删除整个default_price定义。

但是,您正在调用Size.default_price,如果您在类Size上调用它,则不会绑定任何内容,而不是该类的实例。

你想要实际做的是伊萨克凯利建议的那种,但更重要的是。

class ProductOption(models.Model):
    # column definitions

    def __init__(self, *args, **kwargs):
        super(ProductOption, self).__init__(*args, **kwargs)
        if self.size and not self.price:
            self.price = self.size.default_price

这意味着当您实例化ProductOption时,如果还没有价格,它会根据尺寸自动设置价格。

您可能还希望在保存时执行此检查,否则:

po = ProductOption()
po.size = Size.objects.get(pk=1)
po.save()
# po.price is not set now!

po = ProductOption.objects.get(pk=po.pk)
# po.price is set now!

所以,您可以拥有以下内容:

class ProductOption(models.Model):
    # columns

    def __init__(self, *args, **kwargs):
        super(ProductOption, self).__init__(*args, **kwargs)
        self.set_default_price()

    def save(self, *args, **kwargs):
        self.set_default_price()
        super(ProductOption, self).save(*args, **kwargs)

    def set_default_price(self):
        if self.size and not self.price:
            self.price = self.size.default_price

注意super()调用的顺序差异:初始化对象时,我们首先想要调用父__init__,但是在保存时,我们希望(可能)先设置默认值,然后调用父类的save方法。