Websocket connection failed: With django and vue.js

I'm trying to set up websockets to show any new entry in Post model (I'm new with websockets)

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    content = models.TextField()
    status = models.IntegerField(choices=STATUS, default=0)
    author = models.ForeignKey(
        User,
        related_name="blog_posts",
        on_delete=models.CASCADE,
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

This is the consumers.py

class PostConsumer(ListModelMixin, GenericAsyncAPIConsumer):

    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permissions = (permissions.AllowAny,)

For checking if it works I have an html and I'm handling the websockets with vue.js here's the more relevant part of the index.html

    <title>Testing Websockets</title>
  </head>
  <body>
    <div id="app" class="row mt-5">
      <div class="col-1"></div>
      <div class="col-10">
        <div class="card">
          <p class="card-header">Display list of all the posts in Real-Time</p>
          <div class="card-body">
            <table class="table align-middle mb-0 bg-white">
              <thead class="bg-light">
                <tr>
                  <th>Title</th>
                  <th>Status</th>
                  <th>Author</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="post in posts">
                  <td>
                    <p class="fw-normal mb-1">[[ post.title ]]</p>
                  </td>
                  <td>
                    <span
                      class="badge rounded-pill d-inline"
                      :class="{'bg-success': post.status !== 'Draft', 'bg-warning': post.status === 'Draft'}"
                    >
                      [[ post.status ]]
                    </span>
                  </td>
                  <td>[[ post.author ]]</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>

    <script
      src="https://code.jquery.com/jquery-3.6.0.min.js"
      integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
      crossorigin="anonymous"
    ></script>
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa"
      crossorigin="anonymous"
    ></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script>
      vueApp = new Vue({
        el: "#app",
        delimiters: ["[[", "]]"],
        data() {
          return {
            posts: [],
          };
        },
      });

      var ws = new WebSocket("ws://localhost:8001/ws/");
      console.log(this.posts, "CHECKING WEBSOCKETS")
      console.log(ws)
      ws.onopen = function (e) {
        ws.send(
          JSON.stringify({
            action: "list",
            request_id: new Date().getTime(),
          })
        );
      };

      ws.onmessage = function (e) {
        allData = JSON.parse(e.data);
        if (allData.action === "list") {
          vueApp.$data.posts = allData.data;
          vueApp.$forceUpdate();
        } else if (allData.action === "create") {
          vueApp.$data.posts.push(allData.data);
        }
      };
    </script>
  </body>
</html>

    async def connect(self, **kwargs):
        await self.model_change.subscribe()
        await super().connect()

    @model_observer(Post)
    async def model_change(self, message, observer=None, **kwargs):
        await self.send_json(message)

    @model_change.serializer
    def model_serialize(self, instance, action, **kwargs):
        return dict(data=PostSerializer(instance=instance).data, action=action.value)

when I run the in the console logs I see the following message

WebSocket connection to 'ws://localhost:8001/ws/' failed: 

Please let me know if there's anything else that I need to share.

I had a tricky mistake. This is what I had in my settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'user',
    'rest_framework_simplejwt',
    'channels',
    'daphne',
]

I moved channels and daphne to the top of the list and it worked. Like this

INSTALLED_APPS = [
    'channels',
    'daphne',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'user',
    'rest_framework_simplejwt',
]
Back to Top