#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:
Ваш последний пример потенциально может работать с некоторой работой:
- Прежде всего, вам нужно для
__init__
вашего класса, а не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()
Комментарии:
1. Здравствуйте, я пытаюсь использовать это в моем случае, но я понимаю
NameError: name 'self' is not defined
, что использую почти те же модели, у меня есть 2 атрибутаnumber
, иthreshold
оба являются целыми полями, где мне нужноthreshold
, чтобы бытьnumber
* 50class 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: в отчете нет ошибки задания…. Как ваша модель отчета узнала, на какой экземпляр задания вы ссылались при инициализации?