Skip to content
Advertisement

Django: how to write django signal to update field in django?

i want to write a simple django signal that would automatically change the status of a field from live to finished, when i check a button completed.

I have a model that looks like this

class Predictions(models.Model):
    ## other fields are here
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    status = models.CharField(choices=STATUS, max_length=100, default="in_review")
  

class PredictionData(models.Model):
    predictions = models.ForeignKey(Predictions, on_delete=models.SET_NULL, null=True, related_name="prediction_data")
    votes = models.PositiveIntegerField(default=0)
    won = models.BooleanField(default=False)

when i check the won button that is in the PredictionData model, i want to immediately changes the status of the Prediction to finished.

NOTE: i have some tuple at the top of the model.

STATUS = (
    ("live", "Live"),
    ("in_review", "In review"),
    ("pending", "Pending"),
    ("cancelled", "Cancelled"),
    ("finished", "Finished"),
)

Advertisement

Answer

You can make a signal with:

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


@receiver(pre_save, sender=PredictionData)
def update_prediction(sender, instance, *args, **kwargs):
    if instance.won and instance.predictions_id is not None:
        prediction = self.instance.predictions
        prediction.status = 'finished'
        prediction.save(update_fields=('status',))

Note: Signals are often not a robust mechanism. I wrote an article [Django-antipatterns] that discusses certain problems when using signals. Therefore you should use them only as a last resort.


Note: normally a Django model is given a singular name, so Prediction instead of Predictions.

Advertisement