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.

¿Cómo puedo crear automáticamente una entrada de muchos a muchos basada en un campo encontrado en dos modelos en Django?

Tengo el siguiente ejemplo de modelos:

class TestSet(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Class(models.Model):
    name = models.CharField(max_length=50)
    test_set_id = models.ForeignKey(TestSet)

    def __str__(self):
        return self.name

class Test(models.Model):
    title = models.CharField(max_length=50)
    test_set_id = models.ForeignKey(TestSet)

    def __str__(self):
        return self.title

class ClassTest(models.Model):
    class_id = models.ForeignKey(Class)
    test_id = models.ForeignKey(TestSet)
    memo = models.CharField(max_length=250)

    def __str__(self):
        return self.memo

Lo que quiero hacer es que cuando se crea un nuevo objeto de la clase Class o Test, también se cree automáticamente una entrada en la clase ClassTest si su testsetid coincide con las entradas existentes en la base de datos.

Por ejemplo:
1. Supongamos que ya tengo tres objetos Test con testsetid = 1.
2. Creo un nuevo objeto Class con testsetid = 1.
3. Después de crear el nuevo objeto Class, el programa también debería crear 3 nuevas entradas en la clase ClassTest conectando clases con pruebas en base a la coincidencia del campo testsetid.
4. Debería funcionar de la misma manera si se agrega un nuevo objeto Test.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para lograr esta funcionalidad debería utilizar señales de Django. Las señales permiten a ciertos emisores notificar a un conjunto de receptores que algún tipo de acción ha tenido lugar. En este caso, se requiere escuchar la creación de nuevas instancias de las clases Class y Test y automáticamente crear objetos ClassTest si su test_set_id coincide con objetos existentes.

    Primero, necesita importar el módulo ‘signals’ y crear una función que maneje la señal:

    from django.db.models.signals import post_save
    from django.dispatch import receiver
    from miaplicacion.models import Class, Test, ClassTest
    
    @receiver(post_save, sender=Class)
    @receiver(post_save, sender=Test)
    def create_class_test(sender, instance, created, **kwargs):
        if created:
            test_set_id = instance.test_set_id
            matching_tests = Test.objects.filter(test_set_id=test_set_id)
            matching_classes = Class.objects.filter(test_set_id=test_set_id)
            for test in matching_tests:
                for class_ in matching_classes:
                    ClassTest.objects.get_or_create(class_id=class_, test_id=test)
    

    En esta función, primero se verifica si la instancia se creó recientemente. Luego, se obtiene el test_set_id de la instancia y se encuentran todos los objetos Test y Class coincidentes. Finalmente, se recorren todos los matches y se crea un nuevo objeto ClassTest si aún no existe.

    También es necesario asegurarse de importar el modelo ClassTest al principio del archivo.

    Ahora, cada vez que se cree un nuevo objeto Class o Test, se llamará a la función create_class_test y se crearán nuevos objetos ClassTest si coinciden con objetos existentes.

Comments are closed.