1

I'm trying to write a Django custom command that will serve as a daemon for interacting with hardware physically connected to the server. For obvious reasons, I don't want to run hardware-related commands in my Django views; instead, I would rather have the views only interact with models and have the daemon listen for Django post_save signals from the model.

For testing, I have this custom command:

from django.core.management.base import BaseCommand
from django.core.management.base import CommandError

from thermostat.models import Relay
from thermostat.models import Sensor
from thermostat.models import Thermostat

from django.db.models.signals import post_save

import time


class Command(BaseCommand):
  def handle(self, *args, **options):
    post_save.connect(self.saved)

    t = Thermostat.objects.get()
    t.save()

    time.sleep(30)

  def saved(self, sender, **kwargs):
    self.stdout.write(str(sender))
    self.stdout.write(str(kwargs))

The first .save() method is recognized and the expected text is written to the console's stdout. However, it doesn't seem to receive any signals when interacting with the app in the browser or when manually saving instances in the ./manage.py shell CLI.

What am I missing?

Synthead
  • 2,162
  • 5
  • 22
  • 25

1 Answers1

0

Signals don't work like that, I'm afraid. There's no way for the processes that run either the server or the shell to know that you've registered a listener in a completely different process.

The proper way to do this would be with something like Celery: your post_save signal would put something onto the queue, and Celery - which could be running in a different process or even on a different machine - would listen to the queue, pick up the message, and run the task.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895