2011-10-25 12 views
7

Próbuję ustawić domyślną wartość opłaty Report na podstawie atrybutów modelu nadrzędnego. Nie chcę tego robić w save(), ponieważ pole musi zostać przedstawione użytkownikowi, jeśli zdecyduje się przesłonić wartość przed zapisaniem.Czy domyślna wartość pola modelu Django może być zdefiniowana przez funkcję zależną od zagranicznego modelu macierzystego?

Oto trzy metody, które wypróbowałem, oprócz przekazywania tylko wskaźników funkcji (tj. Bez ()). Błędy są zgłaszane po uruchomieniu 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 

Błąd z nr 3 może być, że po prostu nie mają pojęcia, w jaki sposób zastąpić Init prawidłowo. Skopiowałem coś z innej odpowiedzi i poddałem się, gdy to nie zadziałało.

Jeśli żadna z nich nie zadziała, zawsze mogę powrócić do ustawiania opłaty po utworzeniu każdego raportu w widoku, ale wolałbym zrobić to automatycznie po utworzeniu raportu, w celu zachowania zdrowia psychicznego.

EDIT:

skończyło się z nr 3, stały z odpowiedzią Yuji i zmodyfikowane, aby upewnić się ewentualna opłata ustaw z zadajnikami powłoki jakich job.get_fee() chce.

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

Odpowiedz

7

Twój ostatni przykład potencjalnie mogłyby pracować z niektórych prac:

  1. Przede wszystkim trzeba __init__ na swojej klasie, a nie models.Model
  2. trzeba ustawić atrybut po modelu został zainicjowany
  3. Potrzebujesz sprawdzić, czy model został zapisany, czy też twój model będzie powracał do opłaty zastępczej za każdym razem, gdy ją załadujesz.

-

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

To działa. Dziękuję bardzo za Twoją pomoc! – wizpig64

+0

no problemo:) –

+0

Witam, próbuję użyć tego w moim przypadku, ale dostaję 'NameError: nazwa 'self' nie jest zdefiniowana' Używam prawie tych samych modeli, mam 2 atrybuty 'liczba' i' próg 'oba IntegerFields gdzie potrzebne do' threshold' być 'number' * 50 ' klasa poziomu (models.Model) \t grupę = models.ForeignKey (Level_Group) \t = numer models.IntegerField (unikalny = Prawda) # null = Prawda, puste = Prawda \t threshold = models.IntegerField (null = False, blank = True) ' –

Powiązane problemy