- Crea il tuo AdminSite con un semplice override
__init__()
.
- Importa il tuo admin in
urls.py
.
Sostituire l'amministratore di Django e ottenere il comportamento di autodiscover()
è possibile con il minimo sforzo. Ecco una struttura di progetto generato nel tipico django-admin startproject project
moda:
project/
manage.py
project/
__init__.py
settings.py
urls.py
wsgi.py
admin.py # CREATE THIS FILE
progetto/admin.py: (. Credo che abbia più senso per fare questo a livello di progetto)
from django.contrib.admin import * # PART 1
class MyAdminSite(AdminSite):
site_header = "My Site"
def __init__(self, *args, **kwargs):
super(MyAdminSite, self).__init__(*args, **kwargs)
self._registry.update(site._registry) # PART 2
site = MyAdminSite()
progetto/urls.py (frammento):
from . import admin # PART 3
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
Parte 1 è semplice Python. Importando tutto da django.contrib.admin
nello spazio dei nomi, si comporta come una sostituzione drop-in. Suppongo che tu non debba farlo, ma aiuta a preservare le aspettative. Parte 3, collega semplicemente l'amministratore. La parte 2 è il vero trucco.Come dice documentation, autodiscover()
è chiamato a fare il lavoro. Tutto il autodiscover fa passare attraverso INSTALLED_APPS
tentando di importare un file chiamato admin.py
. L'importazione esegue naturalmente il codice e quel codice sta facendo la stessa cosa che si fa per registrare i modelli (ad esempio per decorator e per esempio per method). Nessuna magia Si non è necessario registrare i modelli con l'amministratore personalizzato (come dice la documentazione).
L'individuazione automatica sembra più intelligente rispetto al suo register_to
kwarg. Ciò indica che è possibile chiamare autodiscover() passando il proprio amministratore. No; non ci sono cavi collegati (funzione futura?). L'assegnazione avviene here ed è corretta nell'istanza AdminSite nativa here (o here utilizzando il decoratore). I modelli contribuiti di Django si registrano a quell'istanza, così come tutte le librerie di terze parti. Non è qualcosa a cui aggrapparti.
Ecco il trucco però, _registry
è solo una mappatura del dizionario. Permetti a Django di scoprire automaticamente tutte le cose e quindi solo il copia la mappatura. Ecco perché self._registry.update(site._registry)
funziona. "self" è l'istanza di AdminSite personalizzata, "site" è l'istanza di Django e puoi registrare i tuoi modelli con entrambi.
(Nota finale:.. Se i modelli sono mancanti, è a causa di ordine di importazione Tutto l'iscrizione al AdminSite di Django deve accadere prima di copiare _registry
Registrazione direttamente al vostro amministratore personalizzato è probabilmente la cosa più facile.)
Ho appena provato questo con Django 1.11 con un'istanza AdminSite personalizzata. I modelli registrati prendono tutti i valori predefiniti dal padre AdminSite e non i valori di default rilevanti dell'istanza figlio. Ad esempio, site_title è impostato su un valore diverso nella mia istanza personalizzata e quando si visualizza uno dei modelli che sono stati registrati automaticamente, i valori predefiniti di Django sono visibili solo per tali modelli. I documenti dicono che è necessario registrarsi manualmente quando si utilizza un'istanza personalizzata. https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#django.contrib.admin.autodiscover –
Hai provato il passaggio 'self._registry.update()' dove Django ha auto- registrato/costruito il suo AdminSite e quindi copiare la mappatura? Ciò potrebbe sovrascrivere i valori esistenti, quindi prova a impostare gli attributi AdminSite (come site_title, header, url, ecc.) Dopo quella chiamata in '__init __()'. – JCotton
Sì, ho provato tutto come hai postato. Quindi, se ho capito bene, vuoi che io ridefinisca site_header etc nella funzione __init__ dopo self._registry_update? –