У вас есть несколько вопросов здесь:
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
родительского класса.