2010-03-01 23 views
20

Estoy creando un objeto que rastrea los cambios (Actualizaciones) con respecto a la creación, actualización y eliminación de otros objetos llamados UUIDSyncable en la base de datos.¿Puede un campo generic.GenericForeignKey() ser nulo?

Esto implica cualquier objeto que se extiende save() y delete() métodos de los UUIDSyncable de las clases que se overriden, de tal manera que se crea un nuevo Update objeto a grabar la acción (insertar, actualizar o borrar) y originalmente un campo models.CharField(max_length=64) especificar el UUID pk de los objetos de UUIDSyncable.

En este punto quería actualizar la implementación para usar el campo generic.GenericForeignKey() de Django en lugar del campo de mi único carácter. Esto permitiría acceder al objeto sobre el que se está grabando la actualización de una manera mucho más simple.

Mis aristas problemáticas cuando se desea eliminar un objeto y almacenar que a medida que un objeto Update, como saben Django preformas una eliminación en cascada en el objeto UUIDSyncable se va a eliminar, borrar todos los Update registros anteriores (que no se desea).

Cuando el objeto UUIDSyncable se ha eliminado en mi implementación original, cada objeto Update aún conservará el UUID para informar a las partes externas sobre su eliminación. Mi primera solución para emular esto fue establecer content_object = None justo antes de eliminar el objeto en todos los objetos Update, evitando así la cascada de eliminación.

Admite que generic.GenericForeignKey() no se puede configurar para permitir NULL valores. ¿Hay alguna manera de hacer esto o, de no ser así, cómo se puede utilizar de manera similar un estándar CharField con una clave primaria UUID y un sperate CharField con el nombre del modelo?

Respuesta

24

Quizás necesite establecer null = True en los campos subyacentes content_type y object_id que conforman la clave externa genérica.

+0

He intentado permitir que content_type sea nulo pero no object_id, ya que siempre deseo mantener el valor que el id del objeto (es decir, el caso de charField PK) tiene para referencia posterior (incluso después de que el objeto que especifica) haya sido eliminado. Esto que recuerdo no fue suficiente para permitirme determinar mi objetivo. –

-2

¿Ha intentado con establecer null=True en el GenericForeignKey? Las claves externas genéricas no son un concepto reconocido por la aplicación de base de datos de bajo nivel (es decir, MySQL, SQLite, etc.) por lo que debería poder especificar que el campo sea nulo.

null=True en un campo de la base de datos en Django significa que el campo de la base de datos que representa que los datos se permitió estar vacío, mientras que blank=True cuenta la Django validación formas/modelo que el campo es OK ser dejado vacío por el usuario (o usted, a través de la interfaz de administración). Por lo tanto, es posible que necesite usar ambos para lograr lo que busca.

+2

GenericForeignKey no acepta nulo como un argumento. – Mitch

0

Lo que Daniel Roseman dijo está bien. Solo asegúrese de actualizar su base de datos para permitir Null en esos campos, ya que puede haber creado la tabla sin configurarla.

22

Para los perezosos/pragmática:

class MyModel(models.Model): 
    ...other fields... 
    content_type = models.ForeignKey(ContentType, blank=True, null=True, on_delete=models.SET_NULL) 
    object_id = models.PositiveIntegerField(blank=True, null=True) 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 
+21

Me encanta cuando busco en Google y tropiezo con mi propia respuesta ...d'oh –

+2

gracias, 3 líneas de código es mejor que 1 línea de descripción – dashesy

+0

'content_type' y' object_id' son nombres predeterminados, ni siquiera necesita establecerlos como argumentos 'content_object = generic.GenericForeignKey()' sería suficiente – yamm

Cuestiones relacionadas