Невозможно подписаться на канал Django Rest-frameworks
Я пытаюсь написать API, который бы подписывался на все экземпляры модели Django. Для этого я обратился к документации пакета djangochannelrestframeowork. Я сделал все, как сказано в документации.
Вот как выглядит мой файл asgi.py -
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import yacht_away
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "yacht_away.settings")
django_asgi_app = get_asgi_application()
application = ProtocolTypeRouter(
{
"http": django_asgi_app,
# Just HTTP for now. (We can add other protocols later.)
"websocket": AuthMiddlewareStack(
URLRouter(yacht_away.urls.websocket_urlpatterns)
),
}
)
В моем файле setting.py я объявил -
ASGI_APPLICATION = "yacht_away.asgi.application"
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("redis", 6379)],
},
},
}
Также, в установленных приложениях -
INSTALLED_APPS = [
"channels",
...
]
В моем проекте urls.py -
from messaging.urls import websocket_urlpatterns
websocket_urlpatterns = [
path("api/messaging/", URLRouter(websocket_urlpatterns)),
]
А в apps.py -
from django.urls import path
from messaging.views import CustomerOwnerMessagesView
websocket_urlpatterns = [
path(
"customer/<int:customer>/owner/<int:owner>/",
CustomerOwnerMessagesView.as_asgi(),
),
]
После этого я написал класс представления, который будет создавать запись в базе данных и в то же время, если подписаться на метод subscribe_to_customer_owner_messages_activity, то он должен вернуть только что созданный объект.
class CustomerOwnerMessagesView(
CreateModelMixin, GenericAsyncAPIConsumer, AsyncAPIConsumer
):
serializer_class = CustomerOwnerMessagesSerializer
def get_url_args(self):
url_route = self.scope.get("url_route")
customer = url_route["kwargs"].get("customer")
owner = url_route["kwargs"].get("owner")
return {"customer": customer, "owner": owner}
def get_serializer_context(self, request_id, action):
res = self.get_url_args()
return {"owner": res["owner"], "customer": res["customer"]}
def get_queryset(self, request_id, action) -> QuerySet:
res = self.get_url_args()
return CustomerOwnerMessages.objects.filter(
owner=res["owner"], customer=res["customer"]
)
@model_observer(CustomerOwnerMessages)
async def customer_owner_messages_activity(
self,
message: CustomerOwnerMessagesSerializer,
observer=None,
subscribing_request_ids=[],
**kwargs
):
await self.send_json(message.data)
@customer_owner_messages_activity.serializer
def customer_owner_messages_activity(
self, instance: CustomerOwnerMessages, action, **kwargs
) -> CustomerOwnerMessagesSerializer:
"""This will return the comment serializer"""
return CustomerOwnerMessagesSerializer(instance)
@action()
async def subscribe_to_customer_owner_messages_activity(
self, request_id, **kwargs
):
await self.customer_owner_messages_activity.subscribe(
request_id=request_id
)
Чтобы проверить это, я выполнил следующее -
const ws = new WebSocket("ws://localhost:8000/api/messaging/customer/1/owner/2/")
ws.onmessage = function(e){
console.log(e)
}
ws.send(JSON.stringify({
action: "create",
request_id: new Date().getTime(),
data: {
message: "some message"
}
}))
Но я вижу эту ошибку -
Однако данные хранятся в базе данных.