integerfield - models protect django
Django: el valor por defecto del campo de las instancias del auto modelo. (3)
¿Cómo puedo hacer que el valor predeterminado para un campo sea tomado de objetos existentes de un modelo?
Probé esto y no funcionó:
1)
class ModelA(models.Model):
fieldA = models.CharField(default=self.get_previous())
def get_previous(self):
return ModelA.objects.all()[0].fieldA
NameError: name ''self'' is not defined
2)
class ModelA(models.Model):
fieldA = models.CharField(default=ModelA.get_previous())
@staticmethod
def get_previous():
return ModelA.objects.all()[0].fieldA
NameError: name ''ModelA'' is not defined
3)
class ModelA(models.Model):
fieldA = models.CharField(default=get_previous())
def get_previous():
return ModelA.objects.all()[0].fieldA
NameError: global name ''get_previous'' is not defined
4)
def get_previous():
return ModelA.objects.all()[0].fieldA
class ModelA(models.Model):
fieldA = models.CharField(default=get_previous())
NameError: global name ''ModelA'' is not defined
Tengo claro por qué 3) y 4) no funcionarán. Puedo imaginar por qué 1) no funciona, parece que las propiedades de la clase no pueden referirse a las instancias (es decir, a uno mismo). Puedo imaginar por qué 2) no funcionará; al parecer, no hay ninguna referencia al Modelo A hasta que el intérprete pase por toda la clase.
Entonces, ¿cómo debo abordar esto?
En sus ejemplos, debe eliminar el operador de llamada ()
.
Actualmente, la sentencia se ejecuta inmediatamente en el primer ciclo de lectura y análisis. Al especificar el nombre del símbolo en su lugar, la clase Django recibe un puntero a función que se ejecutará cuando realmente necesite el valor predeterminado.
El ejemplo se convierte en:
def get_previous():
return ModelA.objects.all()[0].fieldA
class ModelA(models.Model):
fieldA = models.CharField(default=get_previous)
Si va a hacer esto para una gran cantidad de campos, considere anular la función de save
, por lo que solo tiene que recuperar el objeto anterior de la base de datos solo una vez.
Opción 1: utilizar formularios modelo . Estos son formularios basados en modelos, en los que puede rellenar fácilmente sus valores con valores de una instancia específica. Esta opción es buena si desea que el valor predeterminado sea algo que se muestre al usuario en formularios, obviamente.
Opción 2: anule el método de guardado del modelo y codifique la comprobación allí: si el campo A es Ninguno, entonces agregue algo de valor. Esta opción es mejor si desea que el valor predeterminado funcione en la capa de datos, y no solo como valores predeterminados de formulario (es decir, también para las instancias que cree de otras maneras).
Si solo desea generar un valor predeterminado, anule el __getattr__()
esta manera:
class ModelA(models.Model):
# your fields
def __getattr__(self, name):
if(name == ''fieldA'' and !self.fieldA):
return self.get_previous()
else:
return super(ModelA, self).__getattr__(name)
Guardar el valor predeterminado del objeto será un poco más difícil. La primera solución que me viene a la mente, anula el método save()
(creo que hay una solución más simple)