Django模型字段的默认值可以由取决于外部父模型的函数定义吗? [英] Can a Django model field's default value be defined by a function dependent on a foreign parent model?
问题描述
我试图默认值报告
的费用是基于父模型的属性。我不想在 save()
中执行此操作,因为如果在保存前选择覆盖该值,则该字段需要提交给用户。
除了传递函数指针(即没有()
)之外,我尝试了三种方法。当我运行 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'对象没有属性'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:na我自己没有定义
#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 __()不需要参数
#3的错误可能是我不知道如何覆盖 init 强>正确我从另一个答案中复制了一些东西,在它没有起作用之后放弃了。
如果这些都不行,我总是可以在我之后设置费用在视图中创建每个报表,但我宁愿在创建报表时自动执行。为了理智,您可以自动执行。
编辑:
结束了#3,修正了Yuji的答案并进行了修改,以确保从shell中设置的任何可能的费用将覆盖job.get_fee()想要的。
$ _ code def __init __(self,* args,** kwargs):
super(Report,self).__ init __(* args,** kwargs)
if self.overridableFee == None和self.job而不是self.pk:
self.overridableFee = self.job.get_fee()
你的最后一个例子可能有一些工作:
- 首先,你需要在你的课上
__ init __
,而不是models.Model
- 你需要设置你的
- 您需要检查模型是否已被保存,否则您的模型将在每次加载时恢复到可覆盖的费用。
-
Job(Model.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)
如果不是self.id:
self.overridableFee = self.job.get_fee()
I'm trying to have the default value of Report
's fee be based on a parent model's attributes. 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.
Here are the three methods I've tried, in addition to passing only function pointers (i.e. without ()
). The errors are raised when I run 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. 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.
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:
- First all, you need to
__init__
on your class, notmodels.Model
- You need to set your attribute after the model has been initialized
- You need check if the model has been saved, or else your model will revert to the overridable fee every time you load it.
-
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()
这篇关于Django模型字段的默认值可以由取决于外部父模型的函数定义吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!