display data in real time and filter on the user (websocket)

Django==4.0.5 this

Ahhh… this appears to be a known issue.

See Django 4.0: ImportError: cannot import name 'LANGUAGE_SESSION_KEY' from 'django.utils.translation' · Issue #1609 · django/channels · GitHub

You can probably try the work-around documented there, or you could try upgrading to Channels 4 and related projects.

It worked for me just to put LANGUAGE_SESSION_KEY = '_language' at the top of channels/auth.py as a workaround. Everything else is working fine for me on django master.

but where is channels/auth.py

Location is as referenced in the error message:

I have the same error :sweat_smile:

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "C:\Users\Abder-Rahmanhe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\channels\routing.py", line 28, in get_default_application
    module = importlib.import_module(path)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "C:\Users\Abder-Rahmanhe\Desktop\Django\Orderline APP\OrderLineApp\OrderLine1\asgi.py", line 15, in <module>
    from channels.auth import AuthMiddlewareStack
  File "C:\Users\Abder-Rahmanhe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\channels\auth.py", line 15, in <module>
    from django.utils.translation import LANGUAGE_SESSION_KEY
ImportError: cannot import name 'LANGUAGE_SESSION_KEY' from 'django.utils.translation' (C:\Users\Abder-Rahmanhe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\django\utils\translation\__init__.py)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\lib\threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\lib\threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Abder-Rahmanhe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\Abder-Rahmanhe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\channels\management\commands\runserver.py", line 107, in inner_run
    application=self.get_application(options),
  File "C:\Users\Abder-Rahmanhe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\channels\management\commands\runserver.py", line 132, in get_application
    return StaticFilesWrapper(get_default_application())
  File "C:\Users\Abder-Rahmanhe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\channels\routing.py", line 30, in get_default_application
    raise ImproperlyConfigured("Cannot import ASGI_APPLICATION module %r" % path)
django.core.exceptions.ImproperlyConfigured: Cannot import ASGI_APPLICATION module 'OrderLine1.asgi'

i add this

from django.conf import settings
from django.contrib.auth import (
    BACKEND_SESSION_KEY,
    HASH_SESSION_KEY,
    SESSION_KEY,
    _get_backends,
    get_user_model,
    load_backend,
    user_logged_in,
    user_logged_out,
)
from django.contrib.auth.models import AnonymousUser
from django.utils.crypto import constant_time_compare
from django.utils.functional import LazyObject
from django.utils.translation import LANGUAGE_SESSION_KEY

from channels.db import database_sync_to_async
from channels.middleware import BaseMiddleware
from channels.sessions import CookieMiddleware, SessionMiddleware

LANGUAGE_SESSION_KEY = '_language'

Note what the workaround says:

(Emphasis added)

The variable needs to be defined before the import so that it is available in the imported module.

@KenWhitesell is it good like that?

I did that but I still have a mistake :sweat_smile:

@KenWhitesell I put in comment the from django.utils.translation import LANGUAGE_SESSION_KEY, I don’t have the error but when I print the user it puts me AnonymousUser I added self.user = self.scope["user"] and print(self.user )

That’s saying that there isn’t an authenticated user making the websocket connection.

Are you logging on to your Django site before opening the websocket?

yes, of course, i log in

But is that happening before you load a page containing the JavaScript that is opening the websocket?

when I load my page, in my server i have AnonymousUser

I understand that.

I’m asking about the sequence of events.

Are you opening the websocket before logging in to the site? This can happen if the JavaScript that you are using to open the websocket appears on the login page itself.

I tried without logging in but it put AnonymousUser, then I tried again while logged in and it still put AnonymousUser

What specifically did you try? Please provide all the details of exactly what you did that created these results.

I must have forgotten something in the code, can I show you everything?

consumers.py

class HubriseOrderConsumer(ListModelMixin, GenericAsyncAPIConsumer):

    def get_queryset(self, **kwargs):
        print(self.scope["user"])
        return HubriseOrder.objects.all()

    serializer_class = HubriseOrderSerializer
    permissions = (permissions.AllowAny,)

    async def connect(self, **kwargs):
        await self.model_change.subscribe()
        await super().connect()

    @model_observer(HubriseOrder)
    async def model_change(self, message, observer=None, **kwargs):
        await self.send_json(message)

    def model_serialize(self, instance, action, **kwargs):
        return dict(data=HubriseOrderSerializer(instance=instance).data, action=action.value)

routing.py

from django.urls import re_path

from . import consumers


# websocket_urlpatterns = [re_path(r"^ws/$", consumers.PostConsumer.as_asgi())]

websocket_urlpatterns = [
    re_path(r"^ws/$", consumers.HubriseOrderConsumer.as_asgi())]

asgi.py

import os

from django.core.asgi import get_asgi_application

from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from channels.security.websocket import AllowedHostsOriginValidator

from myapp.routing import websocket_urlpatterns

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'OrderLine1.settings')

testapp = get_asgi_application()

# application = ProtocolTypeRouter({
#     "http": applicationhttp,
#     "websocket": URLRouter(websocket_urlpatterns),
# })

application = ProtocolTypeRouter({
    "http": testapp,
    "websocket": AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(websocket_urlpatterns),
        )
    ),

})

script javascript in my page html

    <script>
      vueApp = new Vue({
        el: "#app",
        delimiters: ["[[", "]]"],
        data() {
          return {
            HubriseOrder: [],
          };
        },
      });

      var ws = new WebSocket("ws://localhost:8000/ws/");

      ws.onopen = function (e) {
        ws.send(
          JSON.stringify({
            action: "list",
            request_id: new Date().getTime(),
          })
        );
      };

      ws.onmessage = function (e) {
        allData = JSON.parse(e.data);
        if (allData.action === "list") {
          vueApp.$data.HubriseOrder = allData.data;
          vueApp.$forceUpdate();
        } else if (allData.action === "create") {
          vueApp.$data.HubriseOrder.push(allData.data);
        }
      };
    </script>

log
AnonymousUser