Django STATIC_URL with full domain breaks static assets locally

When working locally on a Django project that uses static files and the default static files backend, I am running into an issue when I want to get full absolute urls to the static files instead of only the path.

My settings:

DEBUG = True
BASE_DIR = Path(__file__).resolve().parent.parent
INSTALLED_APPS = ["django.contrib.staticfiles", ...]

STATIC_ROOT = BASE_DIR / "static_root"
STATIC_URL = "/static/"
MEDIA_ROOT = BASE_DIR / "media_root"
MEDIA_URL = "/media/"

STATICFILES_DIRS = (BASE_DIR / "static",)

STATICFILES_FINDERS = (
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
)

Everything works, the admin's CSS is loaded, images work, etc. But when I get the path of a file with this code:

from django.contrib.staticfiles.storage import staticfiles_storage
static_path = staticfiles_storage.url("path_to_folder/some_file.jpg")

That result is a relative path: /static/path_to_folder/some_file.jpg. This is a problem when these urls are used from my external frontend: it now has to prepend the backend's base url to all static assets. But if I'd want to deploy the static assets to S3 for example, in production, then I should not prepend these paths with the domain of the backend.

So what I tried to do was to change the STATIC_URL setting to http://localhost:8000/static/. That way the full url is passed to the frontend, but I could really easily change this setting in the backend in production.

And this is where the problem rears its head: when I change STATIC_URL to http://localhost:8000/static/, none of my static files work anymore, I just get a 404. The admin page also is completely unstyled because of this.

So, to make a long story short: how can I use an absolute STATIC_URL in local development mode with DEBUG=True?

Found the solution here: https://docs.djangoproject.com/en/4.1/ref/contrib/staticfiles/#django.contrib.staticfiles.views.serve.

Simply add this to the end of urls.py:

from django.conf import settings
from django.contrib.staticfiles import views
from django.urls import re_path

if settings.DEBUG:
    urlpatterns += [
        re_path(r'^static/(?P<path>.*)$', views.serve),
    ]

Then the static files will work again even with an absolute URL as the STATIC_URL setting.

Back to Top