vistas tutorial modelos example cual creacion consultas avanzadas django django-models

tutorial - En un método de guardado personalizado modelo django(), ¿cómo debe identificar un nuevo objeto?



modelos en django (11)

Quiero activar una acción especial en el método save () de un objeto modelo de Django cuando estoy guardando un nuevo registro (sin actualizar un registro existente).

¿Es necesario y suficiente el control de (self.id! = None) para garantizar que el auto registro sea nuevo y no se actualice? ¿Algún caso especial que esto pueda pasar por alto?


Es la forma común de hacerlo.

la identificación se dará mientras se guarda la primera vez en el archivo db


La comprobación de self.id supone que id es la clave principal para el modelo. Una forma más genérica sería usar el atajo de teclado pk .

is_new = self.pk is None


La comprobación de self.pk == None no es suficiente para determinar si el objeto se insertará o actualizará en la base de datos.

El Django O / RM presenta un hack especialmente desagradable que es básicamente para verificar si hay algo en la posición PK y, de ser así, hacer una ACTUALIZACIÓN, de lo contrario hacer un INSERT (esto se optimiza para un INSERT si el PK es Ninguno).

La razón por la que tiene que hacer esto es porque puede establecer el PK cuando se crea un objeto. Aunque no es común donde tiene una columna de secuencia para la clave principal, esto no se aplica a otros tipos de campo de clave principal.

Si realmente quiere saber, tiene que hacer lo que O / RM hace y buscar en la base de datos.

Por supuesto que tiene un caso específico en su código y para eso es bastante probable que self.pk == None le diga todo lo que necesita saber, pero no es una solución general.


Llego muy tarde a esta conversación, pero me encontré con un problema con el self.pk que se llena cuando tiene un valor predeterminado asociado.

La forma en que solucioné esto es agregar un campo date_created al modelo

date_created = models.DateTimeField(auto_now_add=True)

Desde aquí puedes ir

created = self.date_created is None


Manera alternativa de verificar self.pk podemos verificar self._state del modelo

self._state.adding is True crea self._state.adding is True

self._state.adding is False updating

Lo obtuve de esta page


Para saber si está actualizando o insertando el objeto (datos), use self.instance.fieldname en su formulario. Defina una función de limpieza en su formulario y verifique si la entrada del valor actual es la misma que la anterior, de lo contrario, la está actualizando.

self.instance y self.instance.fieldname comparan con el nuevo valor


Para una solución que también funciona incluso cuando tienes un UUIDField como clave principal (que, como otros han notado, no es None si solo anulas el save ), puedes conectarte a la señal de post_save de Django. Agregue esto a su models.py :

from django.db.models.signals import post_save from django.dispatch import receiver @receiver(post_save, sender=MyModel) def mymodel_saved(sender, instance, created, **kwargs): if created: # do extra work on your instance, e.g. # instance.generate_avatar() # instance.send_email_notification() pass

Esta devolución de llamada bloqueará el método de save , por lo que puede hacer cosas como notificaciones de activación o actualizar el modelo aún más antes de que su respuesta se envíe por cable, ya sea que esté utilizando formularios o el marco REST Django para llamadas AJAX. Por supuesto, utilícelo de forma responsable y descargue tareas pesadas en una cola de trabajos en lugar de mantener a los usuarios esperando :)



Verifique self.id y el indicador force_insert .

if not self.pk or kwargs.get(''force_insert'', False): self.created = True # call save method. super(self.__class__, self).save(*args, **kwargs) #Do all your post save actions in the if block. if getattr(self, ''created'', False): # So something # Do something else

Esto es útil porque su objeto recién creado (self) tiene su valor pk


más bien use pk en lugar de id :

if not self.pk: do_something()


self.pk is None:

devuelve True dentro de un nuevo objeto Model, a menos que el objeto tenga un UUIDField como primary_key .

El caso de esquina del que podría tener que preocuparse es si existen restricciones de exclusividad en campos distintos al ID (por ejemplo, índices únicos secundarios en otros campos). En ese caso, aún podría tener un nuevo registro en la mano, pero no podrá guardarlo.