Как получить информацию из 'OneToOneField' и использовать ее в admin.py list_display?
Я делаю свой первый сайт, это мой первый большой проект, поэтому я застрял на одной проблеме и не могу ее решить. Вот часть моего кода с ошибкой:
models.py
...
class GField(models.Model):
golf_club_name = models.CharField(
primary_key=True,
max_length=100,
help_text='Enter a golf club (Gfield) name',
)
golf_field_par = models.PositiveIntegerField()
def __str__(self):
return f'{self.golf_club_name}'
class PlayerInstance(models.Model):
...
golf_field_playing = models.OneToOneField(GField, default = 'for_nothoing',on_delete=models.RESTRICT, help_text='where is it taking part?')
now_at_hole = models.IntegerField()
today = models.IntegerField()
R1 = models.IntegerField()
R2 = models.IntegerField()
R3 = models.IntegerField()
R4 = models.IntegerField()
R5 = models.IntegerField()
all_rounds = [R1, R2, R3, R4, R5]
counter = sum(1 for value in all_rounds if value != 0)
par_value = gfield_playing.golf_field_par
total = sum(all_rounds[:counter])
if par_value * counter <= total:
to_par = f'+{total - par_value * counter}'
if par_value*counter>total:
to_par = f'-{par_value * counter - total}'
...
Когда я сохраняю этот код, он отправляет:
par_value = gfield_playing.field_par
^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: у объекта 'OneToOneField' нет атрибута 'field_par'
А насчет admin.py, который отправляет ошибку, когда я попробовал несколько решений из интернета, я действительно сделал 'to_par' хорошо, и исправил Error:
models.py
...
R2 = models.IntegerField()
R3 = models.IntegerField()
R4 = models.IntegerField()
R5 = models.IntegerField()
def calculate_to_par(self):
all_rounds = [self.R1, self.R2, self.R3, self.R4, self.R5]
counter = sum(1 for value in all_rounds if value != 0)
par_value = self.golf_field_playing.golf_field_par
total = sum(all_rounds[:counter])
if par_value * counter <= total:
self.to_par = f'+{total - par_value * counter}'
if par_value*counter>total:
self.to_par = f'-{par_value * counter - total}'
return self.to_par
...
но, когда я попытался добавить 'to_par' в admin.py list_display, он выдал ошибку типа <cant use 'to_par' because it is not callable> или что-то вроде этого, так что после недели попыток решить эту проблему я здесь, чтобы принять некоторую помощь от экспертов.
Я сказал то, что пробовал выше.
Определите свойство [python-doc]:
class PlayerInstance(models.Model):
# …
golf_field_playing = models.OneToOneField(
GField,
default='for_nothoing',
on_delete=models.RESTRICT,
help_text='where is it taking part?',
)
now_at_hole = models.IntegerField()
today = models.IntegerField()
R1 = models.IntegerField()
R2 = models.IntegerField()
R3 = models.IntegerField()
R4 = models.IntegerField()
R5 = models.IntegerField()
@property
def to_par(self):
all_rounds = [self.R1, self.R2, self.R3, self.R4, self.R5]
counter = sum(1 for value in all_rounds if value != 0)
par_value = self.gfield_playing.golf_field_par
total = sum(all_rounds[:counter])
if par_value * counter <= total:
return f'+{total - par_value * counter}'
else:
return f'-{par_value * counter - total}'
Если вы таким образом получаете .to_par
из PlayerInstance
, то это приведет к запуску функции, стоящей за свойством, и возвращению результата.
Примечание: Модели обычно не имеют суффикса
Instance
. Объект из класса всегда называется «экземпляр», называя класс…Instance
, создается впечатление, что переменная является экземпляром класса.