Saltar al contenido

¿Cómo eliminar modelos relacionados uno a uno en cascada en django?

Hola, descubrimos la respuesta a tu búsqueda, desplázate y la encontrarás más abajo.

adjuntas post_delete señal a su modelo por lo que se llama a la eliminación de una instancia de Book o Newspaper:

from django.db.models.signals import post_delete
from django.dispatch import receiver

@receiver(post_delete, sender=Book)
def auto_delete_publish_info_with_book(sender, instance, **kwargs):
    instance.info.delete()

@receiver(post_delete, sender=Newspaper)
def auto_delete_publish_info_with_newpaper(sender, instance, **kwargs):
    instance.info.delete()

Otra solución sencilla anulando save y delete método:

En comparación con la respuesta de @ozgur, descubrí que usar la señal para conectar en cascada la acción de eliminación tiene el mismo efecto que eliminar anulando el Model.delete() método, y también podríamos crear automáticamente el adjunto PublishInfo:

class Book(models.Model):

    info = models.OneToOneField(
        PublishInfo, on_delete=models.CASCADE)

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        if not self.info:
            self.info = Publish.objects.create()
            super().save(*args, **kwargs)

    def delete(self, *args, **kwargs):
        super().delete(*args, **kwargs)
        if self.info:
            self.info.delete()

Solución más estructurada y reutilizable:

Entonces, pronto me di cuenta de que los tres campos y métodos de listado son obviamente redundantes en cada modelo que estaba adjuntando el PublishInfo modelos como campo.

Entonces, ¿por qué no usamos la herencia?

class PublishInfoAttachedModel(models.Model):

    info = models.OneToOneField(
        PublishInfo, related_name='$(class)s',
        on_delete=models.CASCADE)

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        if not self.info:
            self.info = Publish.objects.create()
            super().save(*args, **kwargs)

    def delete(self, *args, **kwargs):
        super().delete(*args, **kwargs)
        if self.info:
            self.info.delete()

    class Meta:
        abstract = True

Recuerda agregar abstract = True en su metaclase.

Entonces, ahora somos libres de agregar PublishInfo en cualquier otro modelo queremos adjuntar ese modelo, y podemos hacer más de uno de esos modelos abstractos:

class Book(PublishInfoAttachedModel, 
           models.Model):
    pass

class NewsPaper(PublishInfoAttachedModel, 
           CommentsAttachedModel,  # if we have other attached model info
           models.Model):
    pass

Observe la models.Model La clase en la lista de superclase final se puede ignorar, escribí esto solo para hacer que las clases sean más obvias como una Model.

Acuérdate de que te permitimos valorar este escrito si diste con la contestación.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags :

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *