es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Django: Cómo eliminar un grupo que está relacionado con un equipo?

Quiero extender el modelo de grupo de Django. Para hacerlo, he creado una clase de Equipo (Team en inglés), que hace referencia al modelo de grupo con un campo OneToOne. La creación y actualización funcionan como se esperaba, pero no logro eliminar el equipo.

# teamapp/models.py

from django.db import models
from rules.contrib.models import RulesModel
from django.contrib.auth.models import Group

class Team(RulesModel):
    group = models.OneToOneField(
        Group,
        on_delete=models.CASCADE,
        primary_key=True,
    )
    name = models.CharField(max_length=80)

def save(self, *args, **kwargs):
    self.update_or_create_group()
    return super().save(*args, **kwargs)

def update_or_create_group(self, *args, **kwargs):
    team_group, _ = Group.objects.update_or_create(
        id=self.pk,
        defaults={"name": self.name},
    )
    self.group = team_group
# teamapp/signals.py

from django.db.models.signals import post_delete
from django.dispatch import receiver
from django.db import transaction
from django.contrib.auth.models import Group
from teamapp.models import Team

@receiver(post_delete, sender=Team)
def delete_group(sender, instance, **kwargs):
    # TODO: Utilizar Celery para una operación asíncrona: https://docs.djangoproject.com/en/3.2/topics/db/transactions/
    transaction.on_commit(lambda: delete_group(instance))

def delete_group(team_instance):
    Group.objects.filter(id=team_instance.group.id).delete()

Algo no está provocando que la señal se active. ¿Existe otra forma?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Hay algunos problemas potenciales con el código tal como está actualmente:

    1. La función receptora de señal delete_group se llama recursivamente dentro de la función transaction.on_commit. Esto podría causar una recursión infinita y errores de desbordamiento de pila. En su lugar, debería llamar a la función independiente delete_group definida en signals.py.
    2. La señal post_delete no se está conectando al modelo Team de ninguna manera. Esto se puede hacer en el método ready de la clase AppConfig para la aplicación teamapp.

    Aquí hay una versión actualizada del código signals.py que debería funcionar:

    # teamapp/signals.py
    from django.db.models.signals import post_delete
    from django.dispatch import receiver
    from django.db import transaction
    from django.contrib.auth.models import Group
    from teamapp.models import Team
    
    
    @receiver(post_delete, sender=Team)
    def delete_group(sender, instance, **kwargs):
        # TODO: Use celery for async operation: https://docs.djangoproject.com/en/3.2/topics/db/transactions/
        transaction.on_commit(lambda: _delete_group(instance))
    
    
    def _delete_group(team_instance):
        Group.objects.filter(id=team_instance.group.id).delete()
    

    Y aquí hay un ejemplo de cómo conectar la señal post_delete en la clase AppConfig:

    # teamapp/apps.py
    from django.apps import AppConfig
    
    
    class TeamappConfig(AppConfig):
        default_auto_field = 'django.db.models.BigAutoField'
        name = 'teamapp'
    
        def ready(self):
            # importar los manejadores de señales
            import teamapp.signals
    

    Con estos cambios, la señal delete_group se activará cada vez que se elimine una instancia de Team.

Comments are closed.