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:
__init__
on your class, not 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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With