[Python] How can I configure a Django Unfold "custom site" with a required URL parameter?

Discussão em 'Python' iniciado por Stack, Janeiro 25, 2025.

  1. Stack

    Stack Membro Participativo

    I'm attempting to create a "custom site" using Django Unfold. I have an existing admin panel configured using the more basic ModelAdmin approach which works nicely. However, I need to create a separate admin panel using the "custom site" feature for use with django-tenants. I want the URL structure to look like: http://localhost:8000/tenant-admin/$tenant-id/. Within the "custom site", Django Tenants will scope the Postgres search path to the correct Postgres schema and the admin will be able to manage all of the models for a given tenant.

    I have defined my custom site as follows:

    from django.contrib import admin
    from django.urls import path
    from unfold.sites import UnfoldAdminSite
    from unfold.admin import ModelAdmin
    from tenant_app.models import Foo


    class TenantAdminSite(UnfoldAdminSite):
    # hopefully not needed -- but this is the first instance of admin:index causing problems
    # index_template = "admin/dashboard.html"

    def get_app_list(self, *args, **kwargs):
    # this lives at apps/tenant_app and is the only app that this TenantAdminSite
    # will use. Not sure if strings are valid here?
    return ["tenant_app"]

    def get_urls(self):
    """
    Add custom URLs to the default admin site, capturing the tenant name.
    """
    from django.urls import reverse

    # Capture the tenant name as part of the URL
    urls = super().get_urls()

    # Add custom URL pattern to handle the index view based on tenant
    custom_urls = [
    path(
    "/tenant-admin/<str:tenant_name>/", self.index_view, name="index"
    ), # Tenant-specific index
    ]

    return custom_urls + urls

    def index_view(self, request, tenant_name):
    """
    A custom view for the index page of the admin, taking the tenant name into account.
    """
    # Use django-tenants' tenant context for the tenant-specific admin
    from django_tenants.utils import tenant_context
    with tenant_context(tenant_name):
    context = self.each_context(request)
    return self.render_to_response(context)

    def index(self, request, schema_name, extra_context={}):
    self.schema_name = schema_name
    return super().index(request, extra_context)


    tenant_admin_site = TenantAdminSite(name="tenant_admin_site")


    @admin.register(Foo, site=tenant_admin_site)
    class FooAdmin(ModelAdmin):
    model = Foo



    ... and urls.py as:

    ...
    path("tenant-admin/<str:schema_name>/", tenant_admin_site.urls),
    ...


    Visiting http://localhost:8000/tenant-admin/01949409-daa3-77e0-b367-229cb0ded71a/ now yields the following error which occurs when the template tries to create a URL using url admin:index:

    Reverse for 'index' with no arguments not found. 2 pattern(s) tried: ['tenant\\-admin/(?P<schema_name>[^/]+)/\\Z', 'tenant\\-admin/(?P<schema_name>[^/]+)//tenant\\-admin/(?P<tenant_name>[^/]+)/\\Z']



    I'm at a bit of a loss with how to proceed. I've tried overriding all of the seemingly relevant methods in my site subclass and trying to define an index value but ... perhaps I just have a fundamental misunderstanding of how or if this approach can work.

    Environment:

    • Python 3.13
    • Django 5 (latest)
    • unfold 0.45.0

    Continue reading...

Compartilhe esta Página