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

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

问题描述

我试图默认值报告的费用是基于父模型的属性。我不想在 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()


解决方案

你的最后一个例子可能有一些工作:


  1. 首先,你需要在你的课上 __ init __ ,而不是 models.Model

  2. 你需要设置你的

  3. 您需要检查模型是否已被保存,否则您的模型将在每次加载时恢复到可覆盖的费用。

-

  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:

  1. First all, you need to __init__ on your class, not models.Model
  2. You need to set your attribute after the model has been initialized
  3. 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屋!

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