DEV Community

Cover image for django-admin: criando um AdminSite customizado sem perder o registro automático dos Models
Eduardo Oliveira
Eduardo Oliveira

Posted on

4

django-admin: criando um AdminSite customizado sem perder o registro automático dos Models

Ao trabalhar com django, principalmente utilizando o django-admin, é bastante comum não nos preocuparmos, sempre, com os models que são registrados ao painel de admin padrão.

O motivo disso é bem simples: na maioria dos casos não precisamos tocar na instância padrão da classe AdminSite, que é a classe que define como o painel admin irá ser exibido.

Quando não precisamos trocar a instância do AdminSite que utilizamos, o registro automático dos models sempre nos satisfaz.

Porém, ao surgir a necessidade de sobrescrever o AdminSite padrão, costumamos perder o registro automático dos models feitos pelos diversos pacotes (libs, bibliotecas, etc.) que instalamos no nosso projeto.

Motivação

A motivação pra se lidar com esse problema, é que em algumas situações precisamos alterar o AdminSite padrão. Um exemplo clássico e que costuma surgir bastante é: quando é preciso ordenar os Apps e os Models na página inicial do nosso admin.

O AdminSite Padrão

Quando executamos o comando abaixo, para iniciar um novo projeto (existem outras variações do comando, não se preocupe), por padrão, teremos o arquivo core/urls.py do código a seguir

django-admin startproject core .
Enter fullscreen mode Exit fullscreen mode
# core/urls.py
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]
Enter fullscreen mode Exit fullscreen mode

Nesse arquivo, é registrada uma instância padrão do AdminSite que, por sua vez, é importada do caminho: django.contrib.admin.site.

Com o projeto em execução (python manage.py runserver), ao realizar login no painel de admin, teremos a seguinte tela:

tela inicial do django-admin

Alterando o AdminSite

Para alterar o AdminSite é bem simples, criando um arquivo core/site.py:

# core/site.py
from django.contrib.admin import AdminSite

class CustomSite(AdminSite):
    pass

site = CustomSite()
Enter fullscreen mode Exit fullscreen mode

E alterando, então, o core/urls.py:

# core/urls.py
from django.urls import path
from .site import site

urlpatterns = [
    path('admin/', site.urls),
]
Enter fullscreen mode Exit fullscreen mode

A tela inicial do admin nesse momento, assume uma outra estética, sem permissão pra visualizar ou editar nada (pois não há nenhum model registrado):

página inicial do admin do django sem models

AdminSite Padrão

No exemplo acima, substituímos o import do admin.site original pelo .site.admin. Podemos alterar, porém, esse código para substituir o AdminSite padrão do projeto e, dessa forma, não perderemos os models registrados automáticamente:

# core/site.py
from django.contrib.admin import AdminSite

class CustomSite(AdminSite):
    def get_app_list(self, request):
        """
        Return a sorted list of all the installed apps that have been
        registered in this site.
        """
        app_dict = self._build_app_dict(request)

        # Sort the apps alphabetically.
        app_list = sorted(app_dict.values(), key=lambda x: x['name'].lower())

        # Sort the models alphabetically within each app.
        for app in app_list:
            app['models'].sort(key=lambda x: x['name'])
            app['models'].reverse()

        return app_list
Enter fullscreen mode Exit fullscreen mode

Foi adicionado, aqui, um código apenas para alterar a ordem dos models dentro dos apps para que possamos ver efeitos visuais na tela (Referência do código aqui). Além disso, foi removida aquela chamada site = CustomSite().

A partir de agora, é preciso reverter o core/urls.py:

# core/urls.py
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]
Enter fullscreen mode Exit fullscreen mode

Além desses dois passos, é preciso criar um core/apps.py onde será criada uma instância da classe AdminConfig definindo quem é o AdminSite padrão:

# core/apps.py
from django.contrib.admin.apps import AdminConfig

class MyAdminConfig(AdminConfig):
    default_site = 'core.site.CustomSite'
Enter fullscreen mode Exit fullscreen mode

Por último, no settings.py:

# core/settings.py

# ...

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

# ...
Enter fullscreen mode Exit fullscreen mode

É preciso substituir o django.contrib.admin pelo core.apps.MyAdminConfig:

# core/settings.py

# ...

INSTALLED_APPS = [
    'core.apps.MyAdminConfig',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

# ...
Enter fullscreen mode Exit fullscreen mode

Resultados

Quando entramos na página inicial do admin agora, temos a seguinte exibição:

django-admin

Quando alteramos o código comentando a seguinte linha, passamos a ter outro resultado:

# app['models'].reverse()
Enter fullscreen mode Exit fullscreen mode

django-admin

O código fonte final desse texto está disponível no GitHub.

Referências

AWS Q Developer image

Your AI Code Assistant

Generate and update README files, create data-flow diagrams, and keep your project fully documented. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (0)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay