mirror of
https://github.com/suitenumerique/docs.git
synced 2026-09-30 13:35:10 +02:00
🐛(backend) serve the static files of the admin without whitenoise
We previously removed whitenoise because its middleware is not compatible is not compatible with the ASGI application. But without it, static file for the admin are not served anymore. This commit allow to serve them using the static view from django. This view should not be used in production but we are only using it for the admin, which is not used a lot and a settings is also added to disable it if you want to serve static from a dedicated nginx for example.
This commit is contained in:
@@ -14,6 +14,7 @@ and this project adheres to
|
||||
|
||||
- 🐛(frontend) hide Leave in the doc menu when not logged in #2626
|
||||
- 🐛(backend) allow to configure settings DATA_UPLOAD_MAX_MEMORY_SIZE
|
||||
- 🐛(backend) serve the static files of the admin without whitenoise
|
||||
|
||||
## [v5.6.0] - 2026-09-03
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ These are the environment variables you can set for the `impress-backend` contai
|
||||
| SEARCH_INDEXER_SECRET | Token required for indexation queries | |
|
||||
| INDEXING_URL | Find application endpoint for indexation | |
|
||||
| SENTRY_DSN | Sentry host | |
|
||||
| SERVE_STATIC_FILES | Serve the files collected in STATIC_ROOT from Django. Disable it when a web server or a CDN serves /static/ instead | True |
|
||||
| SESSION_COOKIE_AGE | duration of the cookie session | 60*60*12 |
|
||||
| SIGNUP_NEW_USER_TO_MARKETING_EMAIL | Register new user to the marketing onboarding. If True, see env LASUITE_MARKETING_* system | False |
|
||||
| SILK_ENABLED | Enable the django-silk request/SQL/cProfile profiler and its /silk/ UI. OFF by default; never enable against production with real users. See documentation/profiling.md | False |
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
"""Test the serving of the files collected in STATIC_ROOT."""
|
||||
|
||||
import pytest
|
||||
|
||||
from core.tests.utils.urls import reload_urls
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def static_root(settings, tmp_path):
|
||||
"""Point STATIC_ROOT to a directory holding a single collected file."""
|
||||
static_file = tmp_path / "admin" / "css" / "login.css"
|
||||
static_file.parent.mkdir(parents=True)
|
||||
static_file.write_text("body {}", encoding="utf-8")
|
||||
|
||||
settings.STATIC_ROOT = str(tmp_path)
|
||||
|
||||
yield tmp_path
|
||||
|
||||
# The URLs are built from the settings, so restore the settings and reload
|
||||
# them to leave the URLs as the next tests expect them.
|
||||
settings.finalize()
|
||||
reload_urls()
|
||||
|
||||
|
||||
def test_urls_static_served(client, settings):
|
||||
"""Collected static files are served, the admin has no assets otherwise."""
|
||||
settings.SERVE_STATIC_FILES = True
|
||||
reload_urls()
|
||||
|
||||
response = client.get("/static/admin/css/login.css")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b"".join(response.streaming_content) == b"body {}"
|
||||
|
||||
|
||||
def test_urls_static_unknown_file(client, settings):
|
||||
"""A file missing from STATIC_ROOT is a 404."""
|
||||
settings.SERVE_STATIC_FILES = True
|
||||
reload_urls()
|
||||
|
||||
response = client.get("/static/admin/css/unknown.css")
|
||||
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_urls_static_disabled(client, settings):
|
||||
"""Serving static files can be delegated to a web server or a CDN."""
|
||||
settings.SERVE_STATIC_FILES = False
|
||||
reload_urls()
|
||||
|
||||
response = client.get("/static/admin/css/login.css")
|
||||
|
||||
assert response.status_code == 404
|
||||
@@ -146,6 +146,13 @@ class Base(Configuration):
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
STATIC_URL = "/static/"
|
||||
STATIC_ROOT = os.path.join(DATA_DIR, "static")
|
||||
# Let Django itself serve the files collected in STATIC_ROOT. The admin is
|
||||
# unusable without them and, since whitenoise was removed, nothing else
|
||||
# serves STATIC_URL. Disable it when a web server or a CDN is placed in
|
||||
# front of the application to serve them.
|
||||
SERVE_STATIC_FILES = values.BooleanValue(
|
||||
True, environ_name="SERVE_STATIC_FILES", environ_prefix=None
|
||||
)
|
||||
MEDIA_URL = "/media/"
|
||||
MEDIA_ROOT = os.path.join(DATA_DIR, "media")
|
||||
MEDIA_BASE_URL = values.Value(
|
||||
@@ -1371,6 +1378,7 @@ class Test(Base):
|
||||
# Static files are not used in the test environment
|
||||
# Tests are raising warnings because the /data/static directory does not exist
|
||||
STATIC_ROOT = None
|
||||
SERVE_STATIC_FILES = False
|
||||
|
||||
CELERY_TASK_ALWAYS_EAGER = values.BooleanValue(True)
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
"""URL configuration for the impress project"""
|
||||
|
||||
import re
|
||||
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from django.contrib import admin
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
from django.urls import include, path, re_path
|
||||
from django.views.static import serve as serve_static
|
||||
|
||||
from drf_spectacular.views import (
|
||||
SpectacularJSONAPIView,
|
||||
@@ -29,6 +32,18 @@ if settings.DEBUG:
|
||||
+ staticfiles_urlpatterns()
|
||||
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
)
|
||||
elif settings.SERVE_STATIC_FILES:
|
||||
# Whitenoise used to serve the files collected in STATIC_ROOT. It was removed,
|
||||
# so serve them from Django instead, otherwise the admin has no assets at all.
|
||||
# Django's `static()` helper only builds this route when DEBUG is on, hence the
|
||||
# explicit pattern.
|
||||
urlpatterns += [
|
||||
re_path(
|
||||
rf"^{re.escape(settings.STATIC_URL.lstrip('/'))}(?P<path>.*)$",
|
||||
serve_static,
|
||||
{"document_root": settings.STATIC_ROOT},
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
if settings.USE_SWAGGER or settings.DEBUG:
|
||||
|
||||
Reference in New Issue
Block a user