2011-10-25 26 views
7

Estoy intentando que el valor predeterminado de la tarifa Report se base en los atributos de un modelo principal. No deseo hacer esto en save(), porque el campo debe presentarse al usuario si elige anular el valor antes de guardarlo.¿Puede el valor predeterminado de un campo de modelo de Django ser definido por una función dependiente de un modelo padre extranjero?

Estos son los tres métodos que he probado, además de pasar solamente los punteros a las funciones (es decir, sin ()). Los errores se producen cuando ejecuto 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 

El error con el nº 3 podría ser que sólo tengo ni idea de cómo reemplazar init correctamente. Copié algo de otra respuesta y desistí después de que no funcionó.

Si ninguno de estos funciona, siempre puedo volver a configurar la tarifa solo después de crear cada informe en la vista, pero prefiero hacerlo automáticamente cuando se crea el informe, para la cordura.

EDIT:

Terminamos yendo con # 3, fijo con la respuesta de Yuji y modificado para asegurarse de que cualquier cargo posible fijar de las sustituciones de concha qué job.get_fee() quiere.

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

Respuesta

7

Su último ejemplo podría potencialmente trabajar con algo de trabajo:

  1. Primero de todo, es necesario __init__ en su clase, no models.Model
  2. Es necesario configurar el atributo después el modelo se ha inicializado
  3. Necesita comprobar si el modelo se ha guardado, de lo contrario su modelo revertirá a la tarifa cancelada cada vez que la cargue.

-

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

Esto funciona. ¡Muchas gracias por su ayuda! – wizpig64

+0

no problemo:) –

+0

Hola, estoy tratando de usar esto en mi caso, pero me sale 'NameError: name 'self' no está definido' estoy usando casi los mismos modelos, tengo 2 atributos' number' y 'threshold 'ambos son IntegerFields donde necesito el' threshold' ser el 'number' * 50 ' Nivel clase (models.Model): \t grupo = models.ForeignKey (Level_Group) \t número = models.IntegerField (único = True) # null = True, blank = True \t threshold = models.IntegerField (null = False, blank = True) ' –

Cuestiones relacionadas