Wie verwende ich die benutzerdefinierte AdminSite-Klasse?
Welche ist die beste Art der Umsetzung meiner eigenen django.contrib.admin.sites.AdminSite
?
Eigentlich habe ich ein problem mit der Registrierung von INSTALLED_APPS
im django.contrib.admin.autodiscover
. Wenn ich meine custom-AdminSite-Klasse in urls.py
es wurden keine apps angezeigt, auf der admin Seite.
Ich fixierte diese mit einem kleinen hack. Ich schrieb diese Klasse:
from django.contrib.admin.sites import site as default_site
class AdminSiteRegistryFix( object ):
'''
This fix links the '_registry' property to the orginal AdminSites
'_registry' property. This is necessary, because of the character of
the admins 'autodiscover' function. Otherwise the admin site will say,
that you havn't permission to edit anything.
'''
def _registry_getter(self):
return default_site._registry
def _registry_setter(self,value):
default_site._registry = value
_registry = property(_registry_getter, _registry_setter)
Und implementieren Sie eigene benutzerdefinierte AdminSite wie diese:
from wltrweb.hacks.django.admin import AdminSiteRegistryFix
from django.contrib.admin import AdminSite
class MyAdminSite( AdminSite, AdminSiteRegistryFix ):
# do some magic
pass
site = MyAdminSite()
So kann ich dieses site
für urls.py
.
Weiß jemand eine bessere Möglichkeit? Da ich Zugriff auf einen var, beginnend mit einem Unterstrich es ist nicht mehr als ein hack. Ich weiß nicht, wie hacks.
Edit: eine Andere Möglichkeit wäre, zu schreiben, die django.contrib.admin.autodiscover
Funktion, aber in diesem Fall hätte ich redundante code.
InformationsquelleAutor der Frage svenwltr | 2011-02-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zitat aus https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#customizing-the-adminsite-class
Ich glaube, dass die meisten expliziten Ansatz, aber es bedeutet auch, dass Sie sich ändern müssen, die register-code in Ihre apps admin.py -Dateien.
Die Annahme scheint zu sein, dass, sobald Sie zu schreiben beginnen, Ihre benutzerdefinierten admin-Website, es wird ziemlich viel projektspezifisch und Sie wissen vorher, welche apps, die Sie einschließen möchten.
Also, wenn Sie nicht wollen, um die Arbeit mit dem hack vor, ich wirklich nur diese zwei Optionen. Ersetzen Sie alle registrieren Anrufe zu Ihren benutzerdefinierten admin-Seite oder registrieren Sie sich die Modelle explizit in Ihrem adminsite-Modul.
InformationsquelleAutor der Antwort Reiner Gerecke
Das Problem
Mithilfe einer benutzerdefinierten Klasse, die von
django.contrib.admin.AdminSite
für die admin-site des Projekts, ohne zu schreiben, benutzerdefinierte Registrierungscode, mit dem Sie Modelle mit der neuen Klasse. Wenn ich 3rd-party-apps mit Ihren eigenen Modellen, die ich lieber nicht haben, zu Bearbeiten benutzerdefinierte Registrierungs-code, nur weil Sie Modelle wurden Hinzugefügt oder entfernt von diesen apps.Die Lösung
Schalten Sie die Instanz erstellt, mit der default-Klasse verwendet, für die admin-site in Ihre eigene Instanz, erstellt mit Ihrer eigenen Klasse vor
django.contrib.admin
'sautodiscover
- Funktion aufgerufen wird. Ich tun dies, indem Sie:Mit einer app, die ausgeführt wird, den Schalter. (Ich meine Projekt-spezifische app namens
core
für meine eigenen Zwecke.)Zwei Möglichkeiten:
Django 1.6 bis 1.9: verwenden
__init__
der app zum ausführen der Schalter. In Django 1.8, erhalten Sie eine deprecation-Warnung aufgrund der änderung in Django 1.9 nachfolgend zitiert. Beachten Sie, dass diese Methode wird Arbeit mit 1,9 auch, weil die Django-Module die geladen werden, wenn Sie den code unten gezeigt geändert wurden in 1.9 so dass Sie nicht mehr das laden von Modellen. Wenn ich mit dieser Methode meinecore/__init__.py
Datei enthält:Django 1,9 und over: verwenden Sie die app-Konfiguration der app zum ausführen der Schalter. Wie der Django-1.9, da die release notes Zustand:
Ich lieber zur Begrenzung der Importe habe ich in der root-Ebene, um das Risiko zu vermeiden, laden von Modellen. Während in der version 1.9 mit der
__init__
Methode oben arbeitenes ist nicht abzusehen, ob 1.10 oder höher version einführen, die eine änderung, die Probleme verursachen wird.Wenn ich diese Methode der
core/__init__.py
setztdefault_app_config = "core.apps.DefaultAppConfig"
und ich habe einecore/apps.py
wie diese:Während es möglich ist, um diese Methode zu verwenden, die mit den Versionen 1.7 und 1.8, es ist ein bisschen riskant, um es mit diesen Versionen. Siehe die Anmerkungen unten.
Platzierung dieser app früher als
django.contrib.admin
imINSTALLED_APPS
Liste. (Dies ist absolut notwendig für 1.7 und höher. In früheren Versionen von Django, es könnte Arbeit in Ordnung, auch wenn die app später alsdjango.contrib.admin
. Jedoch, siehe die Anmerkungen unten.)Hinweise und Vorsichtsmaßnahmen
Die app, führt der switch sollte wirklich der ersten app in der
INSTALLED_APPS
Liste, um minimieren die chance, dass etwas anderes greifen, werden Sie den Wert vonsite
ausdjango.contrib.admin
bevor die Umschaltung erfolgt. Wenn Sie eine andere app schafft es, diesen Wert vor dem Schalter getan ist, dann, dass die andere app einen Verweis auf die alte Website. Heiterkeit wird sicherlich Folgen.Die obige Methode funktioniert nicht gut, wenn zwei apps zu installieren versuchen, Ihre eigenen, neuen Standard-admin-Website-Klasse. Diese müsste behandelt werden auf einer Fall-zu-Fall-basis.
Ist es möglich, dass eine zukünftige Version von Django brechen könnte diese Methode.
Version vor 1.9, zog ich mit
__init__
zu tun Website Umschalten mit der app-Konfiguration, da die Dokumentation zur Initialisierung zeigt an, dass dieready()
- Methode der app-Konfigurationen aufgerufen wird, relativ spät. Zwischen der Zeit, die eine app-Modul ist geladen, und die Zeitready()
genannt wird, wurden Modelle geladen, und in einigen Fällen, es könnte bedeuten, dass ein Modul hat sich der Wert dersite
ausdjango.contrib.admin
vorready
genannt wird. So wie das Risiko zu minimieren, habe ich die app__init__
- code tun, der Schalter.Ich glaube, die Gefahr, die es in der version 1.7 und 1.8, und dass ich durch die Verwendung vermieden
__init__
durchführen, den Standort wechseln, so früh wie möglich existiert nicht in der 1.9. Jeder ist untersagt Module laden zu lassen, bevor alle Anwendungen geladen werden. So tun die Schalter in derready
Rückruf der ersten Anwendung aufgelistet inINSTALLED_APPS
sicher sein sollte. Ich habe ein Upgrade ein großes Projekt auf 1,9 und verwendet die app-Konfiguration Methode, ohne jedes problem.InformationsquelleAutor der Antwort Louis