[Python] Django Admin Theme Switching Between Grappelli and Jazzmin Not Working (Session-Based)

Discussão em 'Python' iniciado por Stack, Março 12, 2025.

  1. Stack

    Stack Membro Participativo

    Problem Statement:


    I am working on a Django e-commerce project and want users to switch between two admin themes: Grappelli and Jazzmin using Django sessions.

    I have implemented a session-based theme switcher, but:

    • The admin panel always loads Grappelli by default.
    • The switch button appears, but clicking it does not apply the correct theme.
    • After switching to Jazzmin, I get a "Page Not Found" error (404).
    Project Setup

    1. Installed Apps (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 is loading by default, even when the session should switch to Jazzmin.

    2. Middleware for Dynamic Theme Switching (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"]


    I suspect modifying settings.INSTALLED_APPS dynamically might not be effective.
    Does Django require a restart for INSTALLED_APPS changes to take effect?

    Middleware is included in 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 Configuration (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
    ]


    Did I miss something in the URL configuration?

    4. Theme Switching View (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/")


    The session updates, but the theme doesn't switch correctly.
    Is the middleware overriding session-based theme switching?

    Main Project 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. Admin Template Modification (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 %}


    The switcher appears, but the session is not applied correctly.
    Is there an issue with how I'm referencing request.session.admin_theme?

    Issue I Am Facing

    1. Theme Always Loads as Grappelli
      • Even when the session should switch to Jazzmin.
    2. Clicking "Switch Theme" Redirects to a 404 Page
      • /admin/ is not loading Jazzmin properly.
    3. Switching Doesn't Persist
      • Even though request.session["admin_theme"] changes, the applied theme does not.
    What I Have Tried

    • Restarted Django server after modifying settings:
      python manage.py runserver
    • Cleared browser cache and cookies to ensure sessions refresh.
    • Checked session updates by printing request.session.admin_theme.
    • Tried different redirect URLs (reverse("admin:index") instead of /admin/).
    • Verified INSTALLED_APPS order and middleware execution.
    Questions

    1. Can INSTALLED_APPS be modified dynamically in middleware, or does Django require a restart?
    2. Why is Jazzmin giving a 404 error when switching?
    3. Is there a better way to apply admin themes dynamically using sessions?
    System Information

    • Django Version: 5.1.3
    • Python Version: 3.12.5
    • Jazzmin Version: 3.0.1
    • Grappelli Version: 4.0.1
    • Database: SQLite
    Expected Behavior

    • /admin/ should load Jazzmin.
    • /grappelli/ should load Grappelli.
    • Clicking Switch Theme should apply the correct theme without errors.
    **Any help would be greatly appreciated! Thanks in advance! **

    Continue reading...

Compartilhe esta Página