Django模型字段的默认值是否可以由依赖于外部父模型的函数定义?

wiz*_*g64 7 python django django-models

我试图将默认值Report的费用基于父模型的属性.我不想这样做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' 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
Run Code Online (Sandbox Code Playgroud)

#3的错误可能是我不知道如何正确覆盖init.我从另一个答案中复制了一些东西,但在它没有用之后放弃了.

如果这些都不起作用,我总是可以在视图中创建每个报告后再设置费用,但我宁愿在创建报告时自动执行此操作,以获得理智.

编辑:

结束#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()
Run Code Online (Sandbox Code Playgroud)

Yuj*_*ita 7

您的最后一个示例可能适用于某些工作:

  1. 首先,你需要__init__上课,而不是models.Model
  2. 初始化模型,需要设置属性
  3. 您需要检查模型是否已保存,否则每次加载模型时模型都将恢复为可覆盖的费用.

-

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() 
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个好主意,因为不可能执行r = Report(); r.job = j1; r.save()` (2认同)