Может ли значение поля модели Django по умолчанию определяться функцией, зависящей от внешней родительской модели?

#python #django #django-models

#python #django #django-модели

Вопрос:

Я пытаюсь, чтобы значение Report fee по умолчанию основывалось на атрибутах родительской модели. Я не хочу этого делать 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
  

Ошибка с # 3 может заключаться в том, что я просто понятия не имею, как правильно переопределить инициализацию. Я скопировал что-то из другого ответа и сдался после того, как это не сработало.

Если ни один из них не будет работать, я всегда могу вернуться к простой настройке платы после создания каждого отчета в представлении, но я бы предпочел делать это автоматически при создании отчета, для здравомыслия.

Редактировать:

В итоге я выбрал # 3, исправленный с помощью ответа Юджи и модифицированный, чтобы убедиться, что любая возможная плата, установленная из оболочки, переопределяет то, что хочет 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()
  

Ответ №1:

Ваш последний пример потенциально может работать с некоторой работой:

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

Комментарии:

1. Здравствуйте, я пытаюсь использовать это в моем случае, но я понимаю NameError: name 'self' is not defined , что использую почти те же модели, у меня есть 2 атрибута number , и threshold оба являются целыми полями, где мне нужно threshold , чтобы быть number * 50 class Level(models.Model): group = models.ForeignKey(Level_Group) number = models.IntegerField(unique=True)#null=True, blank=True threshold = models.IntegerField(null=False,blank=True)

2. Не такая хорошая идея, потому что это невозможно сделать r = Report(); r.job = j1; r.save()

3. Я получаю RelatedObjectDoesNoetExist: в отчете нет ошибки задания…. Как ваша модель отчета узнала, на какой экземпляр задания вы ссылались при инициализации?