首页 > 解决方案 > 相当于 reverse() 的 Django 通道

问题描述

在常规 Django 中,我知道我可以使用reverse来反转 url。

django-channels 中是否有用于反转 websocket url 的等效功能。如果我有以下路由

application = ProtocolTypeRouter({
    "websocket": URLRouter([
        url(r"^foo-websocket/$", FooConsumer, name="foo-example")
    ]),
})

有什么我可以称呼的吗

>>> reverse("foo-example")
"/foo-websocket/"

或者这在 django-channels 中是不可能的?

标签: djangodjango-channels

解决方案


频道没有反转,但作为使用相同 url() 格式的频道 2,我做了以下操作:

  1. 在应用程序中创建url_channels.py文件,因此在我的情况下,它chat/url_channels.py具有以下内容:

    urlpatterns = [
      url(r'ws/chat/(?P<room_name>[-\w]+)/$', ChatConsumer, name='chat_endpoint'),
    ]
    

    注意:你应该已经有了这个文件,通常它在(定义在)中被调用routing.py和使用,像这样:ProtocolTypeRoutermysite/routing.py

    import chat.urls_channels  # usually routings, but in my case it's urls_channels
    
    application = ProtocolTypeRouter({
        'websocket': AuthMiddlewareStack(
            URLRouter(
                chat.urls_channels.urlpatterns
            )
        ),
    })
    
  2. 然后在我的根/基础应用程序中创建mysite/urls_channels.py

    from django.conf.urls import url, include
    
    urlpatterns = [
        url(r'^channels/', include('chat.urls_channels')),
    ]
    
  3. 然后在settings.py添加额外的 URL conf 中:

    ROOT_URLCONF = 'mysite.urls'
    CHANNELS_URLCONF = 'mysite.urls_channels' # new one
    
  4. 然后在我看来,我可以使用标准reverse_lazy调用,但使用频道 URL conf 而不是默认的:

    context['chat_endpoint'] = reverse_lazy("chat_endpoint", 
                                            kwargs={'room_name': str(self.object.pk)}, 
                                            urlconf=settings.CHANNELS_URLCONF)
    

通过这种方式,您有一组用于两件事的通道模式 -ProtocolTypeRouter同时用于reverse呼叫和呼叫,保持事情一致和干燥。

我认为创建实用函数来包装这种类型并自动附加适当的 urlconf 也会很方便reverse_lazy,例如调用它channels_reverse_lazy


推荐阅读