Hi,
I’ve been happily developing my app under wsgi for several months. Now I need some streaming support so I’ve followed the docs to run under uvicorn. But now nothing works.
If I have django debug toolbar enabled, Django complains that my site logo isn’t in the static dir, which should be fine since the server is in debug mode locally. Commenting out debug toolbar from my installed apps does render the page, but my CSS styles aren’t applied. I get a 404 if I try to load the CSS file.
Again, all this works fine under wsgi. It looks like some kind of static files issue - somehow it seems to not be recognising it’s in debug mode or something. I get 404s for things in the static dir:
INFO: 127.0.0.1:49413 - "GET /static/css/dist/styles.css?v=1732118871 HTTP/1.1" 404 Not Found
[WARNING 2024-11-20 16:07:51,977 django.request:248] Not Found: /static/debug_toolbar/js/timer.js None None
[WARNING 2024-11-20 16:07:51,977 django.request:248] Not Found: /static/debug_toolbar/js/timer.js None None
INFO: 127.0.0.1:49414 - "GET /static/debug_toolbar/js/timer.js HTTP/1.1" 404 Not Found
Here’s a traceback:
Environment:
Request Method: GET
Request URL: http://localhost:8000/content/campaign/203/content/2309/edit
Django Version: 5.1.3
Python Version: 3.11.6
Uvicorn version: 0.32.0
Installed Applications:
['core.apps.CoreConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'django.contrib.sites',
'corsheaders',
'defender',
'emailevents',
'feedback',
'payments',
'staticpages',
'teams',
'users',
'allauth',
'allauth.account',
'nested_admin',
'phonenumber_field',
'formset',
'djmoney',
'djstripe',
'anymail',
'django_recaptcha',
'tailwind',
'theme',
'template_partials',
'widget_tweaks',
'recurring',
'debug_toolbar',
'django_browser_reload']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'defender.middleware.FailedLoginMiddleware',
'djangopoc.sentry.EnrichEventMiddleware',
'users.middleware.EnsureMobileVerifiedMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django_ratelimit.middleware.RatelimitMiddleware',
'allauth.account.middleware.AccountMiddleware',
'django.contrib.sites.middleware.CurrentSiteMiddleware',
'teams.middleware.CurrentProjectMiddleware',
'django_browser_reload.middleware.BrowserReloadMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware']
Template error:
In template /.../venv/lib/python3.11/site-packages/debug_toolbar/templates/debug_toolbar/panels/staticfiles.html, error at line 30
The joined path (/images/logo.svg) is located outside of the base path component (/.../core/static)
20 : </ol>
21 : {% else %}
22 : <p>{% trans "None" %}</p>
23 : {% endif %}
24 :
25 : <h4>{% blocktrans count staticfiles|length as staticfiles_count %}Static file{% plural %}Static files{% endblocktrans %}</h4>
26 : {% if staticfiles %}
27 : <dl>
28 : {% for staticfile in staticfiles %}
29 : <dt><strong><a class="toggleTemplate" href="{{ staticfile.url }}">{{ staticfile }}</a></strong></dt>
30 : <dd><samp> {{ staticfile.real_path }} </samp></dd>
31 : {% endfor %}
32 : </dl>
33 : {% else %}
34 : <p>{% trans "None" %}</p>
35 : {% endif %}
36 :
37 :
38 : {% for finder, payload in staticfiles_finders.items %}
39 : <h4>{{ finder }} ({% blocktrans count payload|length as payload_count %}{{ payload_count }} file{% plural %}{{ payload_count }} files{% endblocktrans %})</h4>
40 : <table>
Traceback (most recent call last):
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 883, in _resolve_lookup
current = current[bit]
^^^^^^^^^^^^
During handling of the above exception ('StaticFilesPanel' object is not subscriptable), another exception occurred:
File "/.../venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/debug_toolbar/middleware.py", line 97, in __call__
rendered = toolbar.render_toolbar()
^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/debug_toolbar/toolbar.py", line 84, in render_toolbar
return render_to_string("debug_toolbar/base.html", context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/loader.py", line 62, in render_to_string
return template.render(context, request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/backends/django.py", line 107, in render
return self.template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 171, in render
return self._render(context)
^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/test/utils.py", line 114, in instrumented_test_render
return self.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/defaulttags.py", line 243, in render
nodelist.append(node.render_annotated(context))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/loader_tags.py", line 210, in render
return template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 173, in render
return self._render(context)
^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/test/utils.py", line 114, in instrumented_test_render
return self.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/defaulttags.py", line 327, in render
return nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/defaulttags.py", line 327, in render
return nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1067, in render
output = self.filter_expression.resolve(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 718, in resolve
obj = self.var.resolve(context)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 850, in resolve
value = self._resolve_lookup(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 893, in _resolve_lookup
current = getattr(current, bit)
^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/debug_toolbar/panels/__init__.py", line 103, in content
return render_to_string(self.template, self.get_stats())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/loader.py", line 62, in render_to_string
return template.render(context, request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/backends/django.py", line 107, in render
return self.template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 171, in render
return self._render(context)
^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/test/utils.py", line 114, in instrumented_test_render
return self.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/defaulttags.py", line 327, in render
return nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1008, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/defaulttags.py", line 243, in render
nodelist.append(node.render_annotated(context))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 1067, in render
output = self.filter_expression.resolve(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 718, in resolve
obj = self.var.resolve(context)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 850, in resolve
value = self._resolve_lookup(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/template/base.py", line 917, in _resolve_lookup
current = current()
^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/debug_toolbar/panels/staticfiles.py", line 25, in real_path
return finders.find(self.path)
^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/contrib/staticfiles/finders.py", line 298, in find
result = finder.find(path, all=all)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/contrib/staticfiles/finders.py", line 203, in find
match = self.find_in_app(app, path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/contrib/staticfiles/finders.py", line 216, in find_in_app
if storage and storage.exists(path):
^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/core/files/storage/filesystem.py", line 206, in exists
return os.path.lexists(self.path(name))
^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/core/files/storage/filesystem.py", line 220, in path
return safe_join(self.location, name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../venv/lib/python3.11/site-packages/django/utils/_os.py", line 31, in safe_join
raise SuspiciousFileOperation(
^
Exception Type: SuspiciousFileOperation at /content/campaign/203/content/2309/edit
Exception Value: The joined path (/images/logo.svg) is located outside of the base path component (/.../core/static)
The settings section shows:
DEBUG True
...
STATICFILES_DIRS
[('node_modules',
'/.../theme/static_src/node_modules')]
STATICFILES_FINDERS
['django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder']
STATIC_ROOT '/.../static'
STATIC_URL '/static/'
STORAGES {'default': {'BACKEND': 'storages.backends.s3.S3Storage',
'OPTIONS': {'bucket_name': 'bucket-media',
'file_overwrite': False,
'region_name': 'eu-west-1'}},
'staticfiles': {'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage'}}
The string ‘asgi’ doesn’t appear on the error page at all. I’m just loading a standard (non-async) view.
I’ve also tried running collectstatic but it doesn’t fix the issue.
I’m running uvicorn with: python -m uvicorn djangopoc.asgi:application
Has anyone seen this or know where to start?
Thanks