title: Databinding with Django channels in custom command
body: <p>I start work with Django channels. I need bind data of my model Device. I do it. When I change Device object in admin interface I get message about changing on client (web browser) but I also run simple WebsocketServer by means of custom django management command. And when Device-object has been changed in custom command process I don't receive any message on client. How I can fix it?</p>
  
  <p>devices/models.py</p>
  
  <pre><code>OFFLINE = 0
  ONLINE = 1
  REGISTRATION = 2
  REMOVED = 3
  ERROR = 4
  
  
  STATUS_CHOICES = (
      (OFFLINE, _("Offline")),
      (ONLINE, _("Online")),
      (REGISTRATION, _("Registration")),
      (REMOVED, _("Removed")),
      (ERROR, _("Error")),
  )
  
  
  class Device(models.Model):
      name = models.CharField(max_length=128,
                              null=True, blank=True, default=None, verbose_name=_("Name"))
      created = models.DateTimeField(verbose_name=_("Creation date time"), editable=False)
      modified = models.DateTimeField(verbose_name=_("Last change date time"), blank=True)
  
      removed = models.BooleanField(verbose_name=_("Device has been removed"), default=False)
      remove_date = models.DateTimeField(verbose_name=_("Date of Device removing"),
                                         null=True, blank=True,
                                         default=None)
  
      joined = models.BooleanField(verbose_name=_("Registration status"), default=False)
      date_joined = models.DateTimeField(verbose_name=_("Registration date time"), blank=True, null=True, default=None)
      owner = models.ForeignKey("accounts.User",
                                null=True, blank=True, default=None,
                                verbose_name=_("Who registered"), on_delete=models.SET(None))
  
      status = models.SmallIntegerField(choices=STATUS_CHOICES, blank=True, default=REGISTRATION, verbose_name=_("Status"))
      frozen = models.BooleanField(default=False, verbose_name=_("Device is frozen"))
  </code></pre>
  
  <p>devices/databinding.py</p>
  
  <pre><code>from channels.binding.websockets import WebsocketBinding
  
  from .models import Device
  
  
  class DeviceBinding(WebsocketBinding):
  
      model = Device
      stream = "device"
      fields = ['status', 'joined', 'frozen']
  
      @classmethod
      def group_names(cls, *args, **kwargs):
          return ["binding.devices"]
  
      def has_permission(self, user, action, pk):
          return True  # FIXME: check permission for user
  </code></pre>
  
  <p>project/routing.py</p>
  
  <pre><code>from channels import route_class, route
  from devices.consumers import Demultiplexer
  from devices.databinding import DeviceBinding
  
  channel_routing = [
      route_class(Demultiplexer, path='^/stream/?$'),
      route("binding.device", DeviceBinding.consumer),
  ]
  </code></pre>
  
  <p>devices/consumers.py</p>
  
  <pre><code>from channels.generic.websockets import WebsocketDemultiplexer
  
  
  class Demultiplexer(WebsocketDemultiplexer):
  
      mapping = {
          "device": "binding.device",
      }
  
      def connection_groups(self):
          return ["binding.devices"]
  </code></pre>
  
  <p>My simple custom command where I run custom autobahn WebSockerServer.</p>
  
  <p>project/management/commands/runcustomcommand.py</p>
  
  <pre><code>from django.core.management import BaseCommand
  from project.websocketserver.autobahn_server import WebSocketServer
  
  class Command(BaseCommand):
      help = "Run WebSocket Server"
  
      # A command must define handle()
      def handle(self, *args, **options):
          wss = WebSocketServer()
          wss.start()
  </code></pre>
  
  <p>project/websocketserver/autobahn_server.py</p>
  
  <p>class WebSocketServer(object):</p>
  
  <pre><code>def __init__(self):
      import sys
  
      from twisted.python import log
  
      log.startLogging(sys.stdout)
  
      self.factory = WebSocketServerFactory(
              "ws://{host}:{port}".format(
                      host=settings.WSS_HOST, port=settings.WSS_PORT),
              # debug=False
      )
      self.factory.protocol = MyServerProtocol
      self.factory.setProtocolOptions(
              autoPingInterval=settings.WSS_AUTO_PING_INTERVAL,
              autoPingTimeout=settings.WSS_AUTO_PING_TIMEOUT
      )
  
  def start(self):
      from twisted.internet import reactor
  
      try:
          logger.info("\tSTART SERVER")
          reactor.listenTCP(settings.WSS_PORT, self.factory)
          reactor.run()
      except KeyboardInterrupt:
          pass
      finally:
          self.stop()
  
  def stop(self):
      from twisted.internet import reactor
      reactor.stop()
      logger.info("\tSTOP SERVER")
  </code></pre>
  
  <p>connetion on client (js code):</p>
  
  <pre><code>var ws_path = "ws://127.0.0.1:8001/stream/";
  console.log("Connecting to " + ws_path);
  var webSocket = new WebSocket(ws_path);
  
  webSocket.onopen = function() {
  alert("Connected!.");
  };
  
  webSocket.onmessage = function(message) {
  var data = JSON.parse(message.data);
  alert(data);
  };
  
  webSocket.onerror = function(error) {
  alert("Error: " + error.message);
  };
  </code></pre>
  
  <p>I run:</p>
  
  <pre><code>redis-server
  daphne project.asgi:channel_layer --port 8001
  python manage.py runworker -v2
  python manage.py runserver 0.0.0.0:8000  -v2
  
  python manage.py runcustomcommand
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I accidentally discovered that if add this code in begin of my management command, subsequent changes to the objects come to the client:</p>
  
  <pre><code>from channels import Channel
  Channel("binding.devices").send({})
  </code></pre>
  
  <p>It's like some kind of initialization. But it is strange.</p>