Переключение темы администратора Django между Grappelli и Jazzmin Не работает (на основе сеанса)
Постановка задачи:
Я работаю над проектом электронной коммерции на Django и хочу, чтобы пользователи могли переключаться между двумя темами администратора: Grappelli и Jazzmin, используя Django сессии.
Я реализовал переключатель тем на основе сеанса, но:
- Панель администратора по умолчанию всегда загружает Grappelli.
- Появится кнопка переключения , но при нажатии на нее не будет применена правильная тема.
- После переключения на Jazzmin я получаю сообщение об ошибке "Страница не найдена" (
404
).
Настройка проекта
1. Установленные приложения (settings.py
)
INSTALLED_APPS = [
"grappelli", # Defaulting to Grappelli
"jazzmin", # Want to switch between these two
"colorfield",
"core.apps.CoreConfig", # My core app
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django.contrib.humanize",
]
Grappelli загружается по умолчанию, даже если сессия должна переключиться на Jazzmin.
<время работы/>2. Промежуточное программное обеспечение для динамического переключения тем (core/middleware.py
)
from django.utils.deprecation import MiddlewareMixin
class DynamicAdminThemeMiddleware(MiddlewareMixin):
def process_request(self, request):
from django.conf import settings
if request.session.get("admin_theme") == "grappelli":
settings.INSTALLED_APPS = ["grappelli"] + [app for app in settings.INSTALLED_APPS if app != "jazzmin"]
else:
settings.INSTALLED_APPS = ["jazzmin"] + [app for app in settings.INSTALLED_APPS if app != "grappelli"]
Я подозреваю, что динамическое изменение settings.INSTALLED_APPS
может оказаться неэффективным.
Требуется ли перезапуск Django, чтобы изменения INSTALLED_APPS
вступили в силу?
Промежуточное программное обеспечение включено в settings.py
:
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"core.middleware.DynamicAdminThemeMiddleware", # Custom middleware
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
<время работы/>
3. Настройка URL-адреса (core/urls.py
)
from django.urls import path
from core.views import switch_theme
urlpatterns = [
path("switch_theme/", switch_theme, name="switch_theme"), # Theme switcher
]
Я что-то пропустил в конфигурации URL-адреса?
<время работы/>4. Режим переключения тем (core/views.py
)
from django.shortcuts import redirect
def switch_theme(request):
current_theme = request.session.get("admin_theme", "jazzmin")
if current_theme == "grappelli":
# Switch to Jazzmin – redirect to /admin/
request.session["admin_theme"] = "jazzmin"
request.session.modified = True # Ensure session updates
return redirect("/admin/") # Redirect to Django admin
else:
# Switch to Grappelli – redirect to /grappelli/
request.session["admin_theme"] = "grappelli"
request.session.modified = True # Ensure session updates
return redirect("/grappelli/")
Сеанс обновляется, но тема переключается неправильно.
Переопределяет ли промежуточное программное обеспечение переключение тем на основе сеанса?
Основной проект urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('grappelli/', include('grappelli.urls')),
path('admin/', admin.site.urls),
path("", include("core.urls")),
]
<время работы/>
5. Изменение шаблона администратора (templates/admin/base_site.html
)
{% extends "admin/base.html" %}
{% block branding %}
<h1>My Custom Admin Panel</h1>
{% endblock %}
{% block userlinks %}
{{ block.super }}
<p>DEBUG: Admin Theme is: {{ request.session.admin_theme }}</p>
{% if request.session.admin_theme == "grappelli" %}
<a href="{% url 'core:switch_theme' %}">Switch to Jazzmin</a>
{% else %}
<a href="{% url 'core:switch_theme' %}">Switch to Grappelli</a>
{% endif %}
{% endblock %}
Переключатель появляется, но сеанс применяется неправильно.
Есть ли проблема с тем, как я ссылаюсь request.session.admin_theme
?
Проблема, с которой я столкнулся
- Тема всегда загружается как Grappelli
- Даже когда сессия должна переключиться на Jazzmin.
- Нажатие кнопки "Сменить тему" приведет к перенаправлению на страницу 404
/admin/
неправильно загружается Jazzmin.
- Переключение не сохраняется
- Несмотря на то, что
request.session["admin_theme"]
изменяется, применяемая тема остается неизменной.
- Несмотря на то, что
То, что Я Пробовал
- Перезапустил сервер Django после изменения настроек:
python manage.py runserver
- Очищен кэш браузера и файлы cookie, чтобы обеспечить обновление сеансов.
- Проверил обновления сеанса путем печати
request.session.admin_theme
. - Пробовал разные URL-адреса перенаправления (
reverse("admin:index")
вместо/admin/
). - Проверенный
INSTALLED_APPS
заказ и выполнение промежуточного программного обеспечения.
Вопросы
- Можно ли динамически изменять
INSTALLED_APPS
в промежуточном программном обеспечении, или Django требует перезапуска? - Почему Jazzmin выдает ошибку 404 при переключении?
- Есть ли лучший способ динамически применять темы администрирования с помощью сеансов?
Системная информация
- Версия для Django:
5.1.3
- Версия на Python:
3.12.5
- Джазовая версия:
3.0.1
- Версия Граппелли:
4.0.1
- База данных:
SQLite
Ожидаемое поведение
/admin/
должен загрузиться Jazzmin./grappelli/
следует загрузить Граппелли.- При нажатии кнопки Переключить тему следует применить правильную тему без ошибок.
**Мы будем очень признательны за любую помощь! Заранее спасибо! **
Поскольку INSTALLED_APPS
не может быть изменен во время выполнения, лучший способ реализовать переключение тем - это:
Определите два отдельных сайта администратора (один для Jazzmin, другой для Grappelli).
Используйте переключатель на основе сеанса для динамического назначения активного сайта администратора.
Обеспечьте правильную маршрутизацию URL-адресов, чтобы Django знал, какого администратора загружать.
Создайте собственный сайт администратора для Jazzmin и Grappelli
Изменить core/admin.py
:
from django.contrib.admin import AdminSite
from django.conf import settings
class GrappelliAdminSite(AdminSite):
site_header = "Grappelli Admin"
site_title = "Grappelli Admin"
index_title = "Welcome to Grappelli Admin"
class JazzminAdminSite(AdminSite):
site_header = "Jazzmin Admin"
site_title = "Jazzmin Admin"
index_title = "Welcome to Jazzmin Admin"
# Instances of admin sites
grappelli_admin_site = GrappelliAdminSite(name="grappelli_admin")
jazzmin_admin_site = JazzminAdminSite(name="jazzmin_admin")
Регистрируйте модели на обоих сайтах администратора
В core/admin.py
зарегистрируйте модели на обоих сайтах:
from django.contrib import admin
from .models import Product, Category
from .admin import grappelli_admin_site, jazzmin_admin_site
# Register your models with both admin sites
for model in [Product, Category]:
admin.site.register(model) # Default admin site
grappelli_admin_site.register(model)
jazzmin_admin_site.register(model)
Определите переключатель на основе URL-адреса для панели администратора
Изменить core/urls.py
from django.urls import path, include
from core.views import switch_theme
from core.admin import grappelli_admin_site, jazzmin_admin_site
from django.contrib import admin
urlpatterns = [
path("switch_theme/", switch_theme, name="switch_theme"), # Theme switcher
# Route based on session theme
path("grappelli-admin/", grappelli_admin_site.urls),
path("jazzmin-admin/", jazzmin_admin_site.urls),
# Default Django admin (fallback)
path("admin/", admin.site.urls),
]
Реализуйте режим переключения тем
Изменить core/views.py
:
from django.shortcuts import redirect
def switch_theme(request):
# Toggle between themes
current_theme = request.session.get("admin_theme", "jazzmin")
if current_theme == "grappelli":
request.session["admin_theme"] = "jazzmin"
return redirect("/jazzmin-admin/") # Redirect to Jazzmin admin
else:
request.session["admin_theme"] = "grappelli"
return redirect("/grappelli-admin/") # Redirect to Grappelli admin
Измените шаблон администратора для переключения темы
Изменить templates/admin/base_site.html
:
{% extends "admin/base.html" %}
{% block branding %}
<h1>My Custom Admin Panel</h1>
{% endblock %}
{% block userlinks %}
{{ block.super }}
<p>Current Admin Theme: {{ request.session.admin_theme }}</p>
{% if request.session.admin_theme == "grappelli" %}
<a href="{% url 'switch_theme' %}">Switch to Jazzmin</a>
{% else %}
<a href="{% url 'switch_theme' %}">Switch to Grappelli</a>
{% endif %}
{% endblock %}
Ожидаемое поведение
/grappelli-admin/
→ Загружает Grappelli Admin./jazzmin-admin/
→ Загружает Jazzmin Admin.Нажатие кнопки "Переключить тему" корректно переключает между Jazzmin и Grappelli.
Я надеюсь, что это поможет вам.