API Django + WebSockets
Я использую API и веб-сокеты в Django.
У меня есть HTML-форма, в которой я ввожу количество дней и максимальный результат, нажимаю кнопку, и ничего не происходит. При попытке открыть страницу на http://127.0.0.1:8000/events/London, браузер также пытается установить соединение с WebSockets, используя URL ws://127.0.0.1:8000/ws/London, но сервер не может найти соответствующий обработчик для этого URL и возвращает ошибку 404.
Итак, мне нужно перенаправить клиента на страницу с данными показа мод после того, как клиент введет данные в форму. Пожалуйста, посоветуйте, как исправить ошибку:
[11/May/2023 20:55:04] "GET /events/London/ HTTP/1.1" 200 1676 Not Found: /ws/London/ [11/May/2023 20:55:04] "GET /ws/London/ HTTP/1.1" 404 4822
events.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Events</title>
<script>
var ws_url = 'ws://' + window.location.host + '/ws/' + '{{ city }}' + '/';
var ws = new WebSocket(ws_url);
ws.onmessage = function(event) {
var event_data = JSON.parse(event.data)['event_data'];
var event_list = document.getElementById('event-list');
event_list.innerHTML = '';
for (var i = 0; i < event_data.length; i++) {
var event = event_data[i];
var event_element = document.createElement('div');
event_element.innerHTML = '<h2>' + event['event_name'] + '</h2>' +
'<img src="' + event['event_preview_url'] + '">' +
'<p><a href="' + event['detail_url'] + '">More Info</a></p>' +
'<p>' + event['location'] + '</p>';
event_list.appendChild(event_element);
}
};
function update_events() {
var days = document.getElementById('days').value;
var max_results = document.getElementById('max-results').value;
var message = {
'days': days,
'max_results': max_results
};
ws.send(JSON.stringify(message));
}
</script>
</head>
<body>
<h1>Events in {{ city }}</h1>
<p>Days: <input type="number" id="days" value="14"></p>
<p>Max Results: <input type="number" id="max-results" value="5"></p>
<button onclick="update_events()">Update</button>
<div id="event-list"></div>
</body>
</html>
consumers.py:
import json
from channels.generic.websocket import AsyncWebsocketConsumer
import requests
class EventConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.city = self.scope['url_route']['kwargs']['city']
await self.channel_layer.group_add(
self.city,
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.city,
self.channel_name
)
async def receive(self, text_data):
url = "https://chicmi.p.rapidapi.com/calendar_in_city/"
headers = {
"X-RapidAPI-Key": "мой ключ API",
"X-RapidAPI-Host": "chicmi.p.rapidapi.com"
}
response = requests.get(url, headers=headers)
data = response.json()
events = data["values"]["events"]
event_data = []
for event in events:
event_data.append({
"event_name": event["event_name"],
"event_preview_url": event["event_preview_url"],
"detail_url": event["detail_url"],
"location": event["location"]
})
await self.channel_layer.group_send(
self.city,
{
'type': 'send_event_data',
'event_data': event_data
}
)
async def send_event_data(self, event):
event_data = event['event_data']
await self.send(json.dumps({
'event_data': event_data
}))
routing.py:
from django.urls import path
from . import consumers
websocket_urlpatterns = [
path('ws/<str:city>/', consumers.EventConsumer.as_asgi()),
]
fashionShows/urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('events/<str:city>/', views.events, name='events'),
]
views.py:
from django.shortcuts import render
def events(request, city):
return render(request, 'events.html', {'city': city})
asgi.py:
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'semWork.settings')
application = ProtocolTypeRouter({
"http": AuthMiddlewareStack(
get_asgi_application(),
),
"websocket": URLRouter(
fashionShows.routing.websocket_urlpatterns
),
})