title: Chat Room in Django Channels
body: <p>I have models "Project" and "Room". Every project has own chat room. I am tring to use Django Channels. Unfortunarly, I have error. What I miss and how to fix this error.</p>
  
  <p><strong>ERROR</strong>:</p>
  
  <pre><code>Traceback (most recent call last):
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
      response = get_response(request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
      response = self.process_exception_by_middleware(e, request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\channels\handler.py", line 237, in process_exception_by_middleware
      return super(AsgiHandler, self).process_exception_by_middleware(exception, request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
      response = wrapped_callback(request, *callback_args, **callback_kwargs)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\contrib\auth\decorators.py", line 23, in _wrapped_view
      return view_func(request, *args, **kwargs)
    File "C:\Users\Nurzhan\PycharmProjects\RMS\project\views.py", line 176, in chat_room
      room, created = Room.objects.get_or_create(project=project_code)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
      return getattr(self.get_queryset(), name)(*args, **kwargs)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\query.py", line 475, in get_or_create
      return self._create_object_from_params(lookup, params)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\query.py", line 505, in _create_object_from_params
      obj = self.create(**params)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\query.py", line 397, in create
      obj = self.model(**kwargs)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\base.py", line 537, in __init__
      setattr(self, field.name, rel_obj)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\fields\related_descriptors.py", line 211, in __set__
      self.field.remote_field.model._meta.object_name,
  ValueError: Cannot assign "'1744d0bc-e439-4562-9c29-4e7b2451f39c'": "Room.project" must be a "Project" instance.
  </code></pre>
  
  <p><strong>urls.py</strong>:</p>
  
  <pre><code>url(r'^(?P&lt;project_code&gt;[0-9a-f-]+)/chat_room/$', chat_room, name='chat_room'),
  </code></pre>
  
  <p><strong>settings.py</strong>:</p>
  
  <pre><code>CHANNEL_LAYERS = {
      "default": {
          "BACKEND": "asgi_redis.RedisChannelLayer",
          "CONFIG": {
              "hosts": [os.environ.get('REDIS_URL', 'redis://localhost:6379')],
          },
          "ROUTING": "chat.routing.channel_routing",
      },
  }
  </code></pre>
  
  <p><strong>models.py</strong>:</p>
  
  <pre><code>class Room(models.Model):
      project = models.ForeignKey(Project, on_delete=models.CASCADE)
  
      code = models.UUIDField(_('Code'), primary_key=True, default=uuid.uuid4, editable=False)
  
      def __str__(self):
          return self.code
  
      def get_absolute_url(self):
          return reverse('project:chat_room', args=[self.project_code])
  
  
  class Message(models.Model):
      room = models.ForeignKey(Room, related_name='messages')
  
      handle = models.TextField()
  
      message = models.TextField()
  
      timestamp = models.DateTimeField(default=timezone.now, db_index=True)
  
      def __unicode__(self):
          return '[{timestamp}] {handle}: {message}'.format(**self.as_dict())
  
      def __str__(self):
          return self.__unicode__()
  
      @property
      def formatted_timestamp(self):
          return self.timestamp.strftime('%b %-d %-I:%M %p')
  
      def as_dict(self):
          return {'handle': self.handle, 'message': self.message, 'timestamp': self.formatted_timestamp}
  </code></pre>
  
  <p><strong>views.py</strong>:</p>
  
  <pre><code>def chat_room(request, project_code):
      # If the room with the given project_code doesn't exist, automatically create it upon first visit.
      room, created = Room.objects.get_or_create(project=project_code)
  
      # We want to show the last 50 messages, ordered most-recent-last
      messages = reversed(room.messages.order_by('-timestamp')[:50])
  
      return render(request, "project/chat/room.html", {
          'room': room,
          'messages': messages,
      })
  </code></pre>
  
  <p><strong>consumers.py</strong>:</p>
  
  <pre><code>@channel_session
  def ws_connect(message):
      prefix, project_code = message['path'].strip('/').strip('/').strip('/').strip('/').strip('/').strip('/')
      room = Room.objects.get(project=project_code)
      message.reply_channel.send({"accept": True})
      Group('chat' + project_code).add(message.reply_channel)
      message.channel_session['room'] = room.project
  
  
  @channel_session
  def ws_receive(message):
      project_code = message.channel_session['room']
      room = Room.objects.get(project=project_code)
      data = json.loads(message['text'])
      m = room.messages.create(handle=data['handle'], message=data['message'])
      Group('chat' + project_code).send({'text': json.dumps(m.as_dict())})
  
  
  @channel_session
  def ws_disconnect(message):
      project_code = message.channel_session['room']
      Group('chat' + project_code).discard(message.reply_channel)
  </code></pre>
  
  <p><strong>routing.py</strong>:</p>
  
  <pre><code>channel_routing = [
      route("websocket.connect", ws_connect),
      route("websocket.receive", ws_receive),
      route("websocket.disconnect", ws_disconnect),
  ]
  </code></pre>
  
  <p><strong>chat.js</strong>:</p>
  
  <pre><code>$(document).ready(function(){
    socket = new WebSocket("ws://" + window.location.host + "/chat" + window.location.pathname);
    var name = "";
  
    swal({
      title: 'Your name:',
      input: 'text',
      inputValidator: function (value) {
        return new Promise(function (resolve, reject) {
          if (value) {
            resolve()
          } else {
            reject('You need to write something!')
          }
        })
      }
    }).then(function (result) {
      name = result;
      swal({
        type: 'success',
        html: 'Hello ' + result
      })
    });
  
    socket.onopen = function(){
      $('#chatform').on('submit', function(event) {
        var message = {
          handle: name,
          message: $('#message').val(),
        }
        socket.send(JSON.stringify(message));
        $('#message').val('');
        return false;
      });
    }
  
    socket.onmessage = function(message) {
      var data = JSON.parse(message.data);
      $('#chat').append('&lt;tr&gt;'
      + '&lt;td&gt;' + data.timestamp + '&lt;/td&gt;'
      + '&lt;td&gt;' + data.handle + '&lt;/td&gt;'
      + '&lt;td&gt;' + data.message + ' &lt;/td&gt;'
      + '&lt;/tr&gt;');
      Push.create("Django Channels Example | " + room , {
        body: "New Message",
        icon: 'http://pa1.narvii.com/6184/91c955faf54e625b3467093bea75a6d25b813871_128.gif',
        timeout: 4000,
        onClick: function () {
          window.focus();
          this.close();
        }
      });
    };
  
    if (socket.readyState == WebSocket.OPEN) socket.onopen();
  
  
  });
  </code></pre>