Django: Cómo cascada de una actualización a través de múltiples modelos?

0

Pregunta

Estoy escribiendo una Django base de aplicación para realizar un seguimiento de los objetos (Objekt) y sus tareas de mantenimiento. Objekts puede ser vinculado a una ubicación.

Ubicación (0/1) --- (n) Objekt (1) --- (n) la Tarea

Ubicación, Objekt y Tarea de todos tener un campo de estado con los siguientes valores:

    RED = "red"
    YELLOW = "yellow"
    GREEN = "green"
    STATUS = [
        (RED, "Overdue tasks"),
        (YELLOW, "Pending tasks"),
        (GREEN, "All good"),
    ]

Quiero que el mapa de Ubicación de marcador cambia de color según el estado de los relacionados con la Objekts y ultimatelly Tareas.

He tratado de seguir django mejores prácticas y crear un modelo de la grasa.

from django.db import models
from locationapp.models import Location
from taskapp.models import Task
from rules.contrib.models import RulesModel

class Objekt(RulesModel):
    RED = "red"
    YELLOW = "yellow"
    GREEN = "green"
    STATUS = [
        (RED, "Overdue tasks"),
        (YELLOW, "Pending tasks"),
        (GREEN, "All good"),
    ]
    name = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    location = models.ForeignKey(
        Location, on_delete=models.SET_NULL, null=True, blank=True
    )
    status = models.CharField(max_length=6, choices=STATUS, default=GREEN)

    def set_status(self):
        if Task.objects.filter(objekt=self.id).filter(status=Task.RED).exists():
            self.status = Objekt.RED
        elif Task.objects.filter(objekt=self.id).filter(status=Task.YELLOW).exists():
            self.status = Objekt.YELLOW
        else:
            self.status = Objekt.GREEN

Pero de alguna manera no estoy seguro acerca de mi concepto aquí... ¿Cómo puede una actualización en la Tarea de realizar una actualización en la Objekt. ¿Y cómo la Objekt más desencadenar la actualización sobre la Ubicación si es necesario en absoluto?

django model python
2021-11-22 21:49:18
1

Mejor respuesta

1

Una posible solución es el uso de señales. He implementado de la siguiente, sin el apio por ahora:

# objektapp/apps.py
from django.apps import AppConfig


class ObjektappConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'objektapp'

    def ready(self):
        import objektapp.signals
# objektapp/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.db import transaction
from taskapp.models import Task
from objektapp.models import Objekt

@receiver(post_save, sender=Task)
def set_status(sender, instance, created, **kwargs):
    # TODO: Use celery for async operation: https://docs.djangoproject.com/en/3.2/topics/db/transactions/
    transaction.on_commit(lambda: objekt_update_status(instance))

def objekt_update_status(task_instance):
    objekt = Objekt.objects.get(id=task_instance.objekt.id)

    new_objekt_status = Objekt.GREEN
    if Task.objects.filter(objekt=task_instance.objekt.id, status=Task.RED).exists():
        new_objekt_status = Objekt.RED
    elif Task.objects.filter(objekt=task_instance.objekt.id, status=Task.YELLOW).exists():
        new_objekt_status = Objekt.YELLOW

    if objekt.status != new_objekt_status:
        objekt.status = new_objekt_status
        objekt.save()

Una configuración similar que he hecho en la Ubicación de la modelo, que también reacciona en un post_save de la señal de la Objekt. No estoy seguro de si es el mejor lugar para almacenar el objekt_update_status() en función de la signals.py archivo, pero tratando de poner en el models.py terminó con la circular de error de importación.

2021-11-24 11:19:32

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................