Django ValueError:找不到路径'ws/chat//'的路由

Posted

技术标签:

【中文标题】Django ValueError:找不到路径\'ws/chat//\'的路由【英文标题】:Django ValueError: No route found for path 'ws/chat//'Django ValueError:找不到路径'ws/chat//'的路由 【发布时间】:2021-06-18 23:08:31 【问题描述】:

我正在使用this tutorial from youtube(这里的github链接:LINK)制作一个简单的聊天应用程序。一个潜在的问题是本教程使用 2.x 版本的 django,但我有 3.1.7,但我运行得很好并且很接近,但随后开始出现此错误:

ValueError: No route found for path 'ws/chat//'

查看我的终端时,它不断尝试重新连接,可能是因为我使用的是ReconnectingWebSocket github javascript code。当我运行 redis-cli 并输入“ping”时,我得到“PONG”作为回报,所以我认为它工作正常。

下面是我的代码:

routing.py(我认为这似乎很可能是问题所在)

from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi()), #new django
]

wsgi.py:

import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_project.settings')
application = get_wsgi_application()

settings.py:

WSGI_APPLICATION = 'django_project.wsgi.application'
ASGI_APPLICATION = 'django_project.asgi.application' # older version of django: 'django_project.routing.application'
# Channels redis config:
CHANNEL_LAYERS = 
    'default': 
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': 
            "hosts": [('127.0.0.1', 6379)],
        ,
    ,

views.py:

聊天/views.py

从 django.shortcuts 导入渲染 导入json 从 django.contrib.auth.decorators 导入 login_required from django.utils.safestring import mark_safe

定义索引(请求): 返回渲染(请求,'chat/index.html')

@login_required 定义房间(请求,房间名称): 返回渲染(请求,'chat/room.html', 'room_name_json':房间名 )

urls.py 从 django.urls 导入路径,包括 从 。导入视图

app_name = 'chat'

urlpatterns = [
    path('chat/', views.index, name='index'),
    path('chat/<str:room_name>/', views.room, name='room'),
]

room.html:

% load static %
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>Chat Room</title>
</head>
<body>
    <script src="% static '/reconnecting_websockets.js' %"></script>
    <textarea id="chat-log" cols="100" rows="20"></textarea><br>
    <input id="chat-message-input" type="text" size="100"><br>
    <input id="chat-message-submit" type="button" value="Send">
     room_name|json_script:"room-name" 
    <script>
        const roomName = JSON.parse(document.getElementById('room-name').textContent);

        const chatSocket = new ReconnectingWebSocket(
            'ws://'
            + window.location.host
            + '/ws/chat/'
            + roomName
            + '/'
        );

        chatSocket.onmessage = function(e) 
            const data = JSON.parse(e.data);
            document.querySelector('#chat-log').value += (data.message + '\n'); //grabbing the textarea with id(#) 'chat-log'
        ;

        chatSocket.onclose = function(e) 
            console.error('Chat socket closed unexpectedly');
        ;

        document.querySelector('#chat-message-input').focus();
        document.querySelector('#chat-message-input').onkeyup = function(e) 
            if (e.keyCode === 13)   // enter, return
                document.querySelector('#chat-message-submit').click();
            
        ;

        document.querySelector('#chat-message-submit').onclick = function(e) 
            const messageInputDom = document.querySelector('#chat-message-input');
            const message = messageInputDom.value;
            chatSocket.send(JSON.stringify(
                'message': message,
                'command': 'fetch_messages'
            ));
            messageInputDom.value = ''; //reset value to empty string
        ;
    </script>
</body>
</html>

consumers.py:

聊天/consumers.py

导入 json 从 asgiref.sync 导入 async_to_sync 从 channels.generic.websocket 导入 WebsocketConsumer 从 .models 导入消息 from django.contrib.auth.models 导入用户

类 ChatConsumer(WebsocketConsumer):

def fetch_messages(self, data):
    messages = Message.last_10_messages(self)
    content = 
        'command': 'messages',
        'messages': self.messages_to_json(messages)
    
    self.send_message(content)


def new_message(self, data):
    author_user = User.objects.filter(username='admin')[0]
    message = Message.objects.create(author=author_user, content=data['message'])
    content = 
        'command': 'new_message',
        'message': self.message_to_json(message)
    
    return self.send_chat_message(content)


def messages_to_json(self, messages):
    result = []
    for message in messages:
        result.append(self.message_to_json(message))
    return result

def message_to_json(self, message):
    return 
        'author': message.author.username,
        'content': message.content,
        'timestamp': str(message.timestamp)
    

commands = 
    'fetch_messages': fetch_messages,
    'new_message': new_message



def connect(self):
    self.room_name = self.scope['url_route']['kwargs']['room_name']
    self.room_group_name = 'chat_%s' % self.room_name

    # Join room group
    async_to_sync(self.channel_layer.group_add)(
        self.room_group_name,
        self.channel_name
    )

    self.accept()

def disconnect(self, close_code):
    # Leave room group
    async_to_sync(self.channel_layer.group_discard)(
        self.room_group_name,
        self.channel_name
    )

# Receive message from WebSocket
def receive(self, text_data):
    data = json.loads(text_data)
    self.commands[data['command']](self, data) # either fetch_messages or new_message

def send_chat_message(self, message):
    print('in send_chat_message')
    async_to_sync(self.channel_layer.group_send)( # Send message to room group
        self.room_group_name,
        
            'type': 'chat_message',
            'message': message
        
    )

def send_message(self, message):
    print('message: ' + str(message))
    self.send(text_data=json.dumps(message))

# Receive message from room group
def chat_message(self, event):
    message = event['message']
    content1 = message['message']
    content2 = content1['content']
    #self.send(text_data=json.dumps(content2)) # Send message to WebSocket
    self.send(text_data=json.dumps(content2)) # Send message to WebSocket

【问题讨论】:

你能在你的 asgi.py 中显示代码吗 @seif 我找到了答案,谢谢 【参考方案1】:

解决方案:当我将views.py更改为此时,它起作用了:

@login_required
def room(request, room_name):
    print('~~~DEBUG~~~')
    return render(request, 'chat/room.html', 
        'room_name': room_name

【讨论】:

以上是关于Django ValueError:找不到路径'ws/chat//'的路由的主要内容,如果未能解决你的问题,请参考以下文章

(Python)ValueError:在路径中找不到程序点

pygraphviz ValueError:在路径中找不到程序点[重复]

找不到 Django 404 错误页面...当前路径与最后一个匹配

模板提供了错误的媒体目录路径,Django 找不到图像

找不到页面(404):django无法匹配路径

Django:Heroku 上的生产应用程序找不到带有“路径”urlpattern 的模板