Настройка статики Django Admin в FastAPI ASGI под /dj
Пошаговое руководство по настройке django статические файлы для админ-панели Django в FastAPI через ASGI. Решение 404 ошибок для CSS/JS admin, collectstatic, mount StaticFiles и альтернативы WSGIMiddleware для hybrid fastapi django python.
Как настроить статические файлы Django для корректной работы админ-панели при интеграции с FastAPI через ASGI?
В проекте сочетаются Django и FastAPI. Создан минимальный Django-проект с настройками DEBUG = True и STATIC_URL = ‘static/’. FastAPI приложение монтирует Django под путём “/dj” с помощью get_asgi_application():
import os
import uvicorn
from fastapi import FastAPI
from django.conf import settings
from django.apps import apps
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "conf.settings")
apps.populate(settings.INSTALLED_APPS)
app = FastAPI()
app.mount("/dj", get_asgi_application())
@app.get("/")
def read_root():
return {"Message": "Hello World"}
if __name__ == '__main__':
uvicorn.run(app, host="0.0.0.0", port=8001)
При открытии Django Admin (http://localhost:8001/dj/admin) возникают ошибки 404 для статических файлов, например: “GET /dj/static/admin/css/dashboard.css HTTP/1.1” 404 Not Found.
Какие настройки необходимы для правильной работы статических файлов админ-панели?
Для корректной работы статических файлов django admin при интеграции Django с FastAPI через ASGI под путём /dj настройте STATIC_ROOT в settings.py, выполните python manage.py collectstatic и добавьте в FastAPI app.mount(“/static”, StaticFiles(directory=settings.STATIC_ROOT, html=False)). Это устранит ошибки django admin 404 для CSS/JS вроде /static/admin/css/dashboard.css, поскольку Django генерирует абсолютные пути от STATIC_URL=‘/static/’. Если пути формируются как /dj/static, скорректируйте mount на “/dj/static” или используйте WSGIMiddleware для полного префикса.
Содержание
- Проблема с django admin и статическими файлами в FastAPI
- Настройка settings.py для django статические файлы и admin
- Монтирование Django в FastAPI под /dj
- Обслуживание статики в FastAPI для django admin
- Выполнение collectstatic и проверка путей
- Альтернативы: WSGIMiddleware для fastapi django python
- Отладка django admin 404 и лучшие практики
- Источники
- Заключение
Проблема с django admin и статическими файлами в FastAPI
Представьте: вы запускаете uvicorn, заходите на http://localhost:8001/dj/admin — и бац, панель голая, без стилей. В консоли браузера или логах uvicorn мелькают 404 для /dj/static/admin/css/dashboard.css или похожих. Почему так? Django admin полагается на django статические файлы (CSS, JS, изображения), которые в чистом режиме DEBUG=True обслуживаются автоматически через django.contrib.staticfiles. Но когда вы монтируете Django как ASGI-приложение в FastAPI под /dj с помощью get_asgi_application(), статика “теряется”.
Это классическая засада в hybrid-приложениях fastapi django python. FastAPI не знает о ваших статических файлах Django — он просто проксирует трафик на /dj к Django ASGI, а статика (по умолчанию /static/) уходит мимо. В вашем коде STATIC_URL=‘static/’ подразумевает запросы на /static/…, но ошибка показывает /dj/static/… — вероятно, Django под субпутём добавляет префикс автоматически (из-за REQUEST_PATH или шаблонов). В любом случае, решение простое, но требует трёх шагов: settings, collectstatic и mount в FastAPI.
Stack Overflow описывает похожий случай с ASGI-сервером — там советуют именно collectstatic плюс ручное обслуживание.
Настройка settings.py для django статические файлы и admin
Сначала разберёмся с Django-сторoną. Откройте conf/settings.py и добавьте/проверьте эти параметры. Без них ничего не полетит.
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
# Статические файлы (DEBUG = True уже есть)
STATIC_URL = '/static/' # Абсолютный путь, без /dj!
STATIC_ROOT = BASE_DIR / 'staticfiles' # Куда собирать collectstatic
STATICFILES_DIRS = [] # Опционально, для ваших custom файлов
STATIC_ROOT — ключевой. Это директория, куда collectstatic сливает все статику из apps (включая admin). Без неё Django не знает, откуда тянуть файлы в продакшене или ASGI-режиме.
Если пути генерируются как /dj/static (как в вашей ошибке), попробуйте временно STATIC_URL = ‘/dj/static/’ — но это хак, сломающий другие части. Лучше оставить /static/ и настроить FastAPI соответственно. Ещё добавьте в INSTALLED_APPS ‘django.contrib.staticfiles’ (должно быть по умолчанию).
Сохраните, и переходите к следующему. Не забудьте: в DEBUG=False статика вообще не auto-сервится, так что это универсальное решение.
Монтирование Django в FastAPI под /dj
Ваш код уже хорош — app.mount("/dj", get_asgi_application()) идеально монтирует Django ASGI под субпутём. Но статика? FastAPI её игнорирует. get_asgi_application() возвращает ASGI-приложение Django, которое само по себе не обслуживает статику в dev-режиме ASGI (uvicorn).
Вот улучшенная версия main.py:
import os
from pathlib import Path
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from django.conf import settings
from django.apps import apps
from django.core.asgi import get_asgi_application
from django.core.management import call_command # Для collectstatic в коде
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "conf.settings")
apps.populate(settings.INSTALLED_APPS)
app = FastAPI()
# Монтируем Django под /dj
django_asgi_app = get_asgi_application()
app.mount("/dj", django_asgi_app)
# Тестовый роут
@app.get("/")
def read_root():
return {"Message": "Hello World"}
if __name__ == '__main__':
# Авто-collectstatic при запуске (опционально)
call_command("collectstatic", interactive=False, verbosity=0)
uvicorn.run(app, host="0.0.0.0", port=8001)
Здесь мы добавим mount статики позже. Это базис для fastapi или django интеграции, как рекомендует Yagiz Degirmenci на Stack Overflow.
Обслуживание статики в FastAPI для django admin
Вот магия! После settings добавьте в FastAPI:
# Импорт StaticFiles
from fastapi.staticfiles import StaticFiles
# Монтируем статику Django (ВАЖНО: после settings.populate!)
app.mount("/static", StaticFiles(directory=settings.STATIC_ROOT, html=False), name="static")
html=False — чтобы не парсить index.html как SPA. Теперь /static/admin/css/dashboard.css будет обслуживаться FastAPI напрямую, минуя Django. Почему не /dj/static? Потому что STATIC_URL=‘/static/’ — Django генерит именно такие ссылки в шаблонах admin.
Если в логах упорно /dj/static/… (возможно, из-за subpath middleware), то mount(“/dj/static”, StaticFiles(directory=settings.STATIC_ROOT, html=False)). Протестируйте оба — в 90% случаев первый вариант работает идеально.
DEV Community шаблон использует именно такой mount(“/static”) для Django admin в FastAPI.
Перезапустите uvicorn — admin должен ожить!
Выполнение collectstatic и проверка путей
Без collectstatic статика в STATIC_ROOT пустая. Запустите из корня проекта:
python manage.py collectstatic --noinput
Это соберёт /staticfiles/admin/css/… и т.д. Проверьте ls staticfiles/admin/ — должно быть полно файлов.
Если под /dj пути сломаны:
- Откройте F12 в браузере на /dj/admin.
- Смотрите Network: какой URL для CSS?
- Если /static/… — ок, mount(“/static”).
- Если /dj/static/… — mount(“/dj/static”) или добавьте в settings.py:
USE_TZ = True
FORCE_SCRIPT_NAME = '/dj' # Префикс для subpath
Но FORCE_SCRIPT_NAME редко нужно — лучше статику отдельно. В ASGI это решает 404 для django admin static.
Альтернативы: WSGIMiddleware для fastapi django python
Не нравится get_asgi_application()? Используйте WSGIMiddleware из asgiref — оно проксирует WSGI Django в ASGI FastAPI с полным контролем путей.
Установите: pip install asgiref
from asgiref.wsgi import WSGIMiddleware
from django.core.wsgi import get_wsgi_application
django_wsgi = get_wsgi_application()
app.mount("/dj", WSGIMiddleware(django_wsgi))
Плюс: лучше поддержка subpath, статика через urls.py Django: в urls.py добавьте if settings.DEBUG: urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Минус: чуть медленнее ASGI. Идеально для legacy Django в FastAPI.
Stack Overflow хвалит этот подход от Rehmat.
Отладка django admin 404 и лучшие практики
404 не ушли? Шаги:
- Логи uvicorn: uvicorn.run(…, log_level=“debug”)
- Проверьте STATICFILES_STORAGE — по умолчанию ok.
- DEBUG=True, но для prod Nginx/Apache с alias /static/ -> STATIC_ROOT.
- Очистите кэш браузера.
- Тест: curl http://localhost:8001/static/admin/css/base.css
Лучшие практики для fastapi django python:
- Отдельные settings для hybrid: STATIC_URL всегда абсолютный.
- Docker: volume для staticfiles.
- Pydantic + Django ORM: sync_to_async для баз.
- Не миксуйте много — FastAPI для API, Django для admin/ORM.
Если ничего не помогает, репозиторий fastapi-django-template — готовый старт.
Источники
- Stack Overflow: Is it possible to use FastAPI with Django — Интеграция FastAPI и Django через ASGI с mount статики для admin: https://stackoverflow.com/questions/63726203/is-it-possible-to-use-fastapi-with-django
- Stack Overflow: Static files for Django Admin can’t be found while running ASGI server — Решение 404 статики Django admin в ASGI с collectstatic: https://stackoverflow.com/questions/77623182/static-files-for-django-admin-cant-be-found-while-running-asgi-server
- DEV Community: FastAPI with Django ORM and Admin — Шаблон проекта FastAPI + Django admin со статикой и ORM: https://dev.to/kathmandu/fastapi-with-django-orm-and-admin-1dae
Заключение
Настройка django статические файлы для django admin в FastAPI сводится к settings.py (STATIC_ROOT), collectstatic и app.mount(“/static”, StaticFiles(…)) — и 404 улетучатся. Для субпути /dj это работает стабильно, особенно с ASGI. Выберите WSGIMiddleware, если нужны тонкие настройки. Теперь ваш hybrid-проект fastapi django python готов к бою: быстрая API + мощный admin. Протестируйте, и если что — логи в помощь!
Для интеграции FastAPI с Django admin используйте get_asgi_application() или WSGIMiddleware для монтирования Django под путём /dj. Чтобы исправить 404 для django статические файлы (например, /static/admin/css/dashboard.css), добавьте app.mount("/static", StaticFiles(directory=settings.STATIC_ROOT)) в FastAPI-приложение. Укажите STATIC_URL = '/static/' и выполните collectstatic. Для admin под субпутём монтируйте именно /dj/static или динамически путь из find_spec("django.contrib.admin").origin. Это решает проблемы django admin static и django admin 404 в fastapi django python.
При запуске ASGI-сервера (uvicorn) django admin теряет django статика — добавьте в settings.py: STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles'), выполните python manage.py collectstatic. В urls.py добавьте + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) к urlpatterns для django статические файлы. При DEBUG=True статика обслуживается автоматически, но для FastAPI + Django под /dj настройте веб-сервер или middleware. Это устраняет django admin 404 и проблемы django admin settings в hybrid-приложениях.
В FastAPI монтируйте Django ORM и admin через get_asgi_application() под /django, добавьте fastapi_app.mount("/static", StaticFiles(directory="static")) и mount("/media", StaticFiles(directory="media")) для django статика. Используйте collectstatic, schemas Pydantic с orm_mode=True и sync_to_async для async ORM в python django admin. Для субпути /dj скорректируйте пути статики. Репозиторий с шаблоном: github.com/kathmandu777/fastapi-django-template. Это полное решение для fastapi django python и django admin панель без 404 ошибок.