[英]Can a Django model field's default value be defined by a function dependent on a foreign parent model?
I'm trying to have the default value of Report
's fee be based on a parent model's attributes. 我试图让Report
的默认值基于父模型的属性。 I don't want to do this in save()
, because the field needs to be presented to the user if they choose to override the value before saving. 我不想在save()
执行此操作,因为如果他们选择在保存之前覆盖该值,则需要将该字段呈现给用户。
Here are the three methods I've tried, in addition to passing only function pointers (ie without ()
). 以下是我尝试过的三种方法,除了只传递函数指针(即没有()
)。 The errors are raised when I run python manage.py shell
. 运行python manage.py shell
时会出错。
#1
from django.db import models
class Job(models.Model):
veryImportant = models.IntegerField()
def get_fee(self):
return 2 * self.veryImportant
class Report(models.Model):
job = models.ForeignKey(Job)
overridableFee = models.DecimalField(default=job.get_fee(), max_digits=7, decimal_places=2)
#gives...
#AttributeError: 'ForeignKey' object has no attribute 'get_fee'
#2
from django.db import models
class Job(models.Model):
veryImportant = models.IntegerField()
class Report(models.Model):
job = models.ForeignKey(Job)
overridableFee = models.DecimalField(default=self.set_fee(), max_digits=7, decimal_places=2)
def set_fee(self):
overridableFee = 2 * self.job.veryImportant
#gives...
#NameError: name 'self' is not defined
#3
from django.db import models
class Job(models.Model):
veryImportant = models.IntegerField()
def get_fee():
return 2 * veryImportant
class Report(models.Model):
job = models.ForeignKey(Job)
overridableFee = models.DecimalField(max_digits=7, decimal_places=2)
def __init__(self, *args, **kwargs):
self.overridableFee = self.job.get_fee()
super(models.Model, self).__init__(*args, **kwargs)
#gives...
#TypeError: object.__init__() takes no parameters
The error with #3 could be that I just have no idea how to override init properly. #3的错误可能是我不知道如何正确覆盖init 。 I copied something out of another answer and gave up after it didn't work. 我从另一个答案中复制了一些东西,但在它没有用之后放弃了。
If none of these will work, I can always revert to just setting the fee after I create each Report in the view, but I'd rather do it automatically when the Report is created, for sanity. 如果这些都不起作用,我可以在视图中创建每个报告之后再回复设置费用,但我宁愿在创建报告时自动执行此操作,以获得理智。
EDIT: 编辑:
Ended up going with #3, fixed with Yuji's answer and modified to make sure any possible fee set from the shell overrides what job.get_fee() wants. 结束#3,修复Yuji的答案并修改以确保从shell中设置的任何可能的费用都会覆盖job.get_fee()想要的内容。
def __init__(self, *args, **kwargs):
super(Report, self).__init__(*args, **kwargs)
if self.overridableFee == None and self.job and not self.pk:
self.overridableFee = self.job.get_fee()
Your last example could potentially work with some work: 您的最后一个示例可能适用于某些工作:
__init__
on your class, not models.Model
首先,你需要在你的班级__init__
,而不是models.Model
- -
class Job(models.Model):
veryImportant = models.IntegerField()
def get_fee():
return 2 * veryImportant
class Report(models.Model):
job = models.ForeignKey(Job)
overridableFee = models.DecimalField(max_digits=7, decimal_places=2)
def __init__(self, *args, **kwargs):
super(Report, self).__init__(*args, **kwargs)
if not self.id:
self.overridableFee = self.job.get_fee()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.