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 .
# core/urls.py
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
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:
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()
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),
]
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):
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
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),
]
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'
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',
]
# ...
É 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',
]
# ...
Resultados
Quando entramos na página inicial do admin agora, temos a seguinte exibição:
Quando alteramos o código comentando a seguinte linha, passamos a ter outro resultado:
# app['models'].reverse()
O código fonte final desse texto está disponível no GitHub.
Referências
The Django admin site - Django Documentation
5. How to set ordering of Apps and models in Django admin dashboard - Django Admin Cookbook
Top comments (0)