Django 模型字段的默认值可以由依赖于外部父模型的函数定义吗? [英] Can a Django model field's default value be defined by a function dependent on a foreign parent model?

查看:23
本文介绍了Django 模型字段的默认值可以由依赖于外部父模型的函数定义吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让 Report 费用的默认值基于父模型的属性.我不想在 save() 中执行此操作,因为如果用户选择在保存之前覆盖该值,则需要将该字段呈现给用户.

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.

这里是我尝试过的三种方法,除了只传递函数指针(即没有 ()).当我运行 python manage.py shell 时出现错误.

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

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

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.

最终选择了 #3,修复了 Yuji 的答案并进行了修改,以确保从 shell 设置的任何可能的费用都覆盖了 job.get_fee() 想要的内容.

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:

  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() 

这篇关于Django 模型字段的默认值可以由依赖于外部父模型的函数定义吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆