Я пытаюсь настроить веб-сокеты, чтобы отображать любую новую запись в модели Post (я новичок в веб-сокетах)
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)
Это consumers.py
class PostConsumer(ListModelMixin, GenericAsyncAPIConsumer):
queryset = Post.objects.all()
serializer_class = PostSerializer
permissions = (permissions.AllowAny,)
Чтобы проверить, работает ли он, у меня есть html, и я обрабатываю веб-сокеты с помощью vue.js.
вот более актуальная часть 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/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity = "sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa"
crossorigin = "anonymous"
></script>
<script src = "https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script>
vueApp = new Vue({
el: "#app",
delimiters: ["[[", "]]"],
data() {
return {
posts: [],
};
},
});
var ws = new WebSocket("ws://localhost:8001/ws/");
console.info(this.posts, "CHECKING WEBSOCKETS")
console.info(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)
когда я запускаю в журналах консоли, я вижу следующее сообщение
WebSocket connection to 'ws://localhost:8001/ws/' failed:
Пожалуйста, дайте мне знать, если есть что-то еще, чем мне нужно поделиться.
Обновлено: Я следил за этим уроком на YouTube





У меня была хитрая ошибка. Вот что было у меня в 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',
]
Я переместил каналы и Daphne в начало списка, и это сработало. Так
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',
]