many - onetoonefield django
OneToOneField y eliminaciĆ³n (2)
Dado que el Profile
vincula con el User
, es el modelo dependiente en la relación. Por lo tanto, cuando elimina un usuario, elimina todos los modelos dependientes. Sin embargo, cuando elimina un perfil, dado que el User
no depende del perfil, no se elimina.
Desafortunadamente, según los docs on_delete
Django, no hay on_delete
regla on_delete
que elimine las relaciones con los padres. Para hacerlo, puede sobrescribir el método de delete
del Profile
:
class Profile(models.Model):
# ...
def delete(self, *args, **kwargs):
self.user.delete()
return super(self.__class__, self).delete(*args, **kwargs)
Entonces al hacer:
Profile.objects.get(...).delete()
también eliminará el usuario del perfil. Sin embargo, no se llamará al método de eliminación cuando se eliminen los perfiles utilizando querysets (que es lo que se llama en Django Admin), ya que Django usa SQL DELETE para eliminar objetos de forma masiva:
Profile.objects.filter(...).delete()
En ese caso, según lo recomendado por Django docs , tendrá que usar la señal post_delete
( docs ).
from django.dispatch import receiver
from django.db.models.signals import post_delete
@receiver(post_delete, sender=Profile)
def post_delete_user(sender, instance, *args, **kwargs):
if instance.user: # just in case user is not specified
instance.user.delete()
Tengo el siguiente modelo:
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User)
# ...
def __unicode__(self):
return u''%s %s'' % (self.user.first_name, self.user.last_name)
Cuando utilizo el administrador de Django para eliminar al usuario, el perfil también se elimina, que es lo que quiero. Sin embargo, cuando se utiliza el administrador de Django para eliminar el perfil, el usuario no se elimina, que no es lo que quiero. ¿Cómo puedo hacer que eliminar el perfil también elimine al usuario?
Use una señal en el método de eliminación del Profile
para ir y eliminar el Usuario relacionado:
from django.db.models.signals import post_delete
def delete_related_user(sender, **kwargs):
deleted_profile = kwargs[''instance'']
deleted_profile.user.delete()
post_delete.connect(delete_related_user, sender=Profile)