【问题标题】:How to get query parameters from Django Channels?如何从 Django Channels 获取查询参数?
【发布时间】:2017-10-28 15:20:44
【问题描述】:

我需要从 Django Channels 访问查询参数 dict。

网址可能如下所示:ws://127.0.0.1:8000/?hello="world"

如何像这样检索“世界”:query_params["hello"]

【问题讨论】:

    标签: python django websocket django-channels


    【解决方案1】:

    在 websocket 上连接 message.content 字典包含 query_string。

    import urlparse
    def ws_connect(message):
        params = urlparse.parse_qs(message.content['query_string'])
        hello = params.get('hello', (None,))[0]
    

    入门文档 (http://channels.readthedocs.io/en/stable/getting-started.html) 暗示 query_string 包含在 message.content 路径中,但似乎并非如此。

    下面是聊天应用程序示例的工作 consumer.py,其中房间在查询字符串中传递:

    import urlparse
    from channels import Group
    from channels.sessions import channel_session
    
    @channel_session
    def ws_message(message):
        room = message.channel_session['room']
        Group("chat-{0}".format(room)).send({"text": "[{1}] {0}".format(message.content['text'], room)})
    
    @channel_session
    def ws_connect(message):
        message.reply_channel.send({"accept": True})
        params = urlparse.parse_qs(message.content['query_string'])
        room = params.get('room',('Not Supplied',))[0]
        message.channel_session['room'] = room
        Group("chat-{0}".format(room)).add(message.reply_channel)
    
    @channel_session
    def ws_disconnect(message):
        room = message.channel_session['room']
        Group("chat-{0}".format(room)).discard(message.reply_channel)
    

    【讨论】:

    • 在python3中,urlparse被重命名为urllib.parse。请参阅 (python 2) docs 的顶部。
    • 在 Channels 2 中,等价于 scope['query_string'],它返回一个字节字符串。因此,如果您想在消费者中使用 unicode 字符串,您可以使用 parse_qs(self.scope['query_string'].decode('utf8'))
    【解决方案2】:

    为频道 3 更新:

    from urllib.parse import parse_qs
    
    # Types
    class Scope(TypedDict):   
        query_string: bytes
    
    scope: Scope
    query_params: Dict[str, List[str]]
    
    # Parse query_string
    query_params = parse_qs(scope["query_string"].decode())
    
    print(query_params["access_token"][-1])
    

    如果您经常这样做,您可以将它放在一个中间件中并将您的 ASGI 应用程序包装在其中。比如:

    class QueryParamsMiddleware(BaseMiddleware):
        async def __call__(self, scope, receive, send):
            scope = dict(scope)
    
            scope["query_params"] = parse_qs(scope["query_string"].decode())
    
            return await super().__call__(scope, receive, send)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-13
      • 2014-12-26
      • 2020-01-27
      • 2018-07-22
      相关资源
      最近更新 更多