Wie kann man grundlegende Django-Administratorvorlagen überschreiben und erweitern?

125

Wie überschreibe ich eine Admin-Vorlage (z. B. admin / index.html) und erweitere sie gleichzeitig (siehe https://docs.djangoproject.com/de/dev/ref/contrib/admin/#overriding-vs-replacing) -an-admin-template )?

Erstens - Ich weiß, dass diese Frage bereits gestellt und beantwortet wurde (siehe Django: Überschreiben UND Erweitern einer App-Vorlage ), aber wie die Antwort besagt, ist sie nicht direkt anwendbar, wenn Sie den Vorlagenladeprogramm app_directories verwenden (das ist der größte Teil der Zeit).

Meine derzeitige Problemumgehung besteht darin, Kopien zu erstellen und daraus zu erweitern, anstatt direkt aus den Administratorvorlagen zu erweitern. Dies funktioniert gut, ist aber sehr verwirrend und fügt zusätzliche Arbeit hinzu, wenn sich die Admin-Vorlagen ändern.

Es könnte an ein benutzerdefiniertes Extend-Tag für die Vorlagen denken, aber ich möchte das Rad nicht neu erfinden, wenn es bereits eine Lösung gibt.

Nebenbei bemerkt: Weiß jemand, ob dieses Problem von Django selbst angegangen wird?

Semmel
quelle
1
Das Kopieren der Administratorvorlagen, das Erweitern und das Überschreiben / Hinzufügen von Blöcken ist am effizientesten, wenn auch angesichts des aktuellen Status von Django kein optimaler Workflow. Ich habe in drei Jahren der Arbeit keine andere Möglichkeit gesehen, das zu tun, was Sie versuchen :)
Brandon
Nun - ich weiß nicht, ob das eine gute Sache ist oder nicht, aber zumindest sind Leute wie Sie zu dem gleichen Schluss gekommen. Das ist gut zu hören. :)
Semmel

Antworten:

101

Update :

Lesen Sie die Dokumente für Ihre Version von Django. z.B

https://docs.djangoproject.com/de/1.11/ref/contrib/admin/#admin-overriding-templates https://docs.djangoproject.com/de/2.0/ref/contrib/admin/#admin-overriding -Vorlagen

Ursprüngliche Antwort von 2011:

Ich hatte vor ungefähr anderthalb Jahren das gleiche Problem und fand auf djangosnippets.org einen netten Template Loader , der dies einfach macht. Es ermöglicht Ihnen , eine Vorlage in einer bestimmten Anwendung zu erweitern, Ihnen die Möglichkeit, Ihr eigenes zu erstellen admin / index.html , die den admin / index.html Vorlage aus dem Admin - App erweitert. So was:

{% extends "admin:admin/index.html" %}

{% block sidebar %}
    {{block.super}}
    <div>
        <h1>Extra links</h1>
        <a href="https://stackoverflow.com/admin/extra/">My extra link</a>
    </div>
{% endblock %}

Ich habe ein vollständiges Beispiel für die Verwendung dieses Vorlagenladers in einem Blogbeitrag auf meiner Website gegeben.

hey Mann
quelle
18
Als Referenz; Das betreffende Snippet wurde in eine Django-App konvertiert und ist in PyPi (pip / easy_install) als django-apptemplates verfügbar: pypi.python.org/pypi/django-apptemplates
Romløk
9
Nur um 100% explizit zu sein: Die obige Lösung wird für neuere Versionen von Django (mindestens 1.4) NICHT MEHR ARBEITEN, da eine der Funktionen, die das Skript verwendet, abgeschrieben wird. Die aktualisierte Quelle finden Sie hier
OldTinfoil
2
Beachten Sie, dass dies mit Django 1.8 weiterhin funktioniert, das Setup jedoch auf besondere Weise erfolgen muss (siehe Beispiel app_namespace.Loader-Setup ). Der Django-App-Namespace-Template-Loader ist auch eine funktionierende Alternative zu dem Fall , django-apptemplatesdass er eines Tages möglicherweise nicht mehr funktioniert.
Peterino
Diese Antwort war sehr gut für die älteren Django-Versionen. Ab sofort ist eine andere Antwort von Cheng relevanter. stackoverflow.com/a/29997719/7344164
SoftwareEnggUmar
70

Da Django 1.8 die aktuelle Version ist, müssen Sie keine Symlinks erstellen, den Administrator / die Vorlagen in Ihren Projektordner kopieren oder Middlewares installieren, wie in den obigen Antworten vorgeschlagen. Folgendes ist zu tun:

  1. Erstellen Sie die folgende Baumstruktur (empfohlen in der offiziellen Dokumentation )

    your_project
         |-- your_project/
         |-- myapp/
         |-- templates/
              |-- admin/
                  |-- myapp/
                      |-- change_form.html  <- do not misspell this

Hinweis : Der Speicherort dieser Datei ist nicht wichtig. Sie können es in Ihre App einfügen und es wird weiterhin funktionieren. Solange sein Standort von Django entdeckt werden kann. Wichtiger ist, dass der Name der HTML-Datei mit dem ursprünglichen HTML-Dateinamen von django übereinstimmen muss.

  1. Fügen Sie diesen Vorlagenpfad zu Ihren settings.py hinzu :

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')], # <- add this line
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
  2. Identifizieren Sie den Namen und den Block, den Sie überschreiben möchten. Dies geschieht durch einen Blick in das Verzeichnis admin / templates von django. Ich benutze virtualenv, daher ist der Pfad für mich hier:

    ~/.virtualenvs/edge/lib/python2.7/site-packages/django/contrib/admin/templates/admin

In diesem Beispiel möchte ich das Formular zum Hinzufügen eines neuen Benutzers ändern. Die für diese Ansicht verantwortliche Vorlage lautet change_form.html . Öffnen Sie die Datei change_form.html und suchen Sie den {% block%}, den Sie erweitern möchten.

  1. Schreiben Sie in Ihre change_form.html Folgendes :

    {% extends "admin/change_form.html" %}
    {% block field_sets %}
         {# your modification here #}
    {% endblock %}
  2. Laden Sie Ihre Seite und Sie sollten die Änderungen sehen

Cheng
quelle
Es reicht immer noch nicht aus, die Hauptvorlage "index.html" zu erweitern, ohne alle Blöcke zu kopieren. Eine Lösung besteht darin, einige ../in den "Exetends" -Pfad zu schreiben und den ursprünglichen Pfad eindeutiger anzugeben {% extends "../../admin/templates/admin/index.html" %}. Link zur Antwort
Hynekcer
1
Ich denke, in TEMPLATES sollten wir 'DIRS' verwenden: [os.path.join (BASE_DIR, 'templates')],
Raul Reyes
Dies ist die Art von Thread, die den Fehler in SO perfekt veranschaulicht. Ein Framework wird aktualisiert und die Frage ist nicht mehr relevant, sondern eine Abschreckung vom richtigen Weg. Tolle Antwort hier. RTFM Kinder.
Derek Adair
Danke für diese Antwort. Mit Ausnahme von "Der Speicherort dieser Datei ist nicht wichtig." Hat alles hervorragend funktioniert.
Jaswanth Manigundan
54

Wenn Sie das überschreiben müssen admin/index.html, können Sie den Parameter index_template von festlegenAdminSite .

z.B

# urls.py
...
from django.contrib import admin

admin.site.index_template = 'admin/my_custom_index.html'
admin.autodiscover()

und platzieren Sie Ihre Vorlage in <appname>/templates/admin/my_custom_index.html

Ingwerlime
quelle
5
Brillant! Auf diese Weise können Sie {% extends "admin/index.html" %}von my_custom_index.html aus auf die Django-Administratorvorlage verweisen, ohne sie zu kopieren. Danke dir.
Mattmc3
3
@Semmel sollte dies als die richtige Antwort markieren, da dies der einfachste Ansatz ist, bei dem integrierte Django-Funktionen verwendet werden und keine benutzerdefinierten Vorlagenlader erforderlich sind.
MrColes
17

Mit django1.5 (mindestens) können Sie die Vorlage definieren, die Sie für eine bestimmte verwenden möchtenmodeladmin

Siehe https://docs.djangoproject.com/de/1.5/ref/contrib/admin/#custom-template-options

Sie können so etwas tun

class Myadmin(admin.ModelAdmin):
    change_form_template = 'change_form.htm'

Mit change_form.htmleiner einfachen HTML-Vorlage, die erweitert wird admin/change_form.html(oder nicht, wenn Sie es von Grund auf neu machen möchten)

Maazza
quelle
9

Chengs 'Antwort ist richtig, jedoch kann laut den Admin-Dokumenten nicht jede Admin-Vorlage auf diese Weise überschrieben werden: https://docs.djangoproject.com/de/1.9/ref/contrib/admin/#overriding-admin-templates

Vorlagen, die pro App oder Modell überschrieben werden können

Nicht jede Vorlage in Contrib / Admin / Templates / Admin kann pro App oder Modell überschrieben werden. Folgendes kann:

app_index.html
change_form.html
change_list.html
delete_confirmation.html
object_history.html

Für Vorlagen, die auf diese Weise nicht überschrieben werden können, können Sie sie dennoch für Ihr gesamtes Projekt überschreiben. Platzieren Sie einfach die neue Version in Ihrem Templates / Admin- Verzeichnis. Dies ist besonders nützlich, um benutzerdefinierte 404- und 500-Seiten zu erstellen

Ich musste die login.html des Administrators überschreiben und daher die überschriebene Vorlage in diese Ordnerstruktur einfügen:

your_project
 |-- your_project/
 |-- myapp/
 |-- templates/
      |-- admin/
          |-- login.html  <- do not misspell this

(ohne den Unterordner myapp im Administrator) Ich habe nicht genug Ansehen, um Cheng's Beitrag zu kommentieren. Deshalb musste ich dies als neue Antwort schreiben.

Matyas
quelle
Vielen Dank für das Feedback Hyneker Ich hoffe, meine Antwort ist klarer und direkter auf den Punkt.
Matyas
Ja, es ist hilfreich zu wissen, dass Vorlagen auf Projektebene angepasst werden können, auch wenn einige davon optional auf Anwendungsebene geändert werden können.
Hynekcer
5

Der beste Weg, dies zu tun, besteht darin, die Django-Administratorvorlagen in Ihr Projekt einzufügen. Ihre Vorlagen wären also in, templates/adminwährend die Standard-Django-Admin-Vorlagen in wären template/django_admin. Dann können Sie Folgendes tun:

templates / admin / change_form.html

{% extends 'django_admin/change_form.html' %}

Your stuff here

Wenn Sie Bedenken haben, die Bestandsvorlagen auf dem neuesten Stand zu halten, können Sie sie in SVN-Externe oder ähnliches einbinden.

Chris Pratt
quelle
Die Verwendung von SVN-Externals ist eine großartige Idee. Das Problem, das sich daraus ergibt, ist, dass alle meine Übersetzer alle diese Vorlagen übersetzen (da makemessages die Übersetzungszeichenfolgen aus allen Administratorvorlagen sammelt), was viel zusätzliche Arbeit bedeutet, wenn Sie mit mehreren Sprachen arbeiten. Vielleicht gibt es eine Möglichkeit, diese Vorlagen von Makemessages auszuschließen?
Semmel
Verwenden Sie das --ignoreArgument mit makemessages. Siehe: docs.djangoproject.com/de/dev/ref/django-admin/#makemessages
Chris Pratt
Ich denke, die andere Antwort passt besser zu meinem Bedürfnis. Aber ich mag Ihre Lösung und denke, es ist eine gute Alternative, wenn Sie nicht mit Ihren Vorlagenladern herumspielen möchten.
Semmel
5

Ich konnte keine einzige Antwort oder keinen Abschnitt in den offiziellen Django-Dokumenten finden, der alle Informationen enthielt, die ich zum Überschreiben / Erweitern der Standard-Admin-Vorlagen benötigte. Daher schreibe ich diese Antwort als vollständigen Leitfaden und hoffe, dass sie hilfreich ist für andere in der Zukunft.

Angenommen, die Standard-Django-Projektstruktur:

mysite-container/         # project container directory
    manage.py
    mysite/               # project package
        __init__.py
        admin.py
        apps.py
        settings.py
        urls.py
        wsgi.py
    app1/
    app2/
    ...
    static/
    templates/

Folgendes müssen Sie tun:

  1. In mysite/admin.pyeiner Unterklasse erstellen AdminSite:

    from django.contrib.admin import AdminSite
    
    
    class CustomAdminSite(AdminSite):
        # set values for `site_header`, `site_title`, `index_title` etc.
        site_header = 'Custom Admin Site'
        ...
    
        # extend / override admin views, such as `index()`
        def index(self, request, extra_context=None):
            extra_context = extra_context or {}
    
            # do whatever you want to do and save the values in `extra_context`
            extra_context['world'] = 'Earth'
    
            return super(CustomAdminSite, self).index(request, extra_context)
    
    
    custom_admin_site = CustomAdminSite()

    Stellen Sie sicher, dass Sie custom_admin_sitein admin.pyIhre Apps importieren und Ihre Modelle darauf registrieren, um sie auf Ihrer benutzerdefinierten Admin-Site anzuzeigen (wenn Sie möchten).

  2. In mysite/apps.pyeine Unterklasse erstellen AdminConfigund Satz default_sitezu admin.CustomAdminSiteaus dem vorherigen Schritt:

    from django.contrib.admin.apps import AdminConfig
    
    
    class CustomAdminConfig(AdminConfig):
        default_site = 'admin.CustomAdminSite'
  3. In mysite/settings.pyErsetzen Sie django.admin.sitein INSTALLED_APPSmit apps.CustomAdminConfig(Ihrer benutzerdefinierten Admin - app Config aus dem vorherigen Schritt).

  4. In mysite/urls.pyErsetzen admin.site.urlsaus der Admin - URLcustom_admin_site.urls

    from .admin import custom_admin_site
    
    
    urlpatterns = [
        ...
        path('admin/', custom_admin_site.urls),
        # for Django 1.x versions: url(r'^admin/', include(custom_admin_site.urls)),
        ...
    ]
  5. Erstellen Sie die Vorlage, die Sie ändern möchten, in Ihrem templatesVerzeichnis, und behalten Sie dabei die in den Dokumenten angegebene Standardverzeichnisstruktur für Django-Administratorvorlagen bei . Wenn Sie beispielsweise Änderungen vorgenommen haben admin/index.html, erstellen Sie die Datei templates/admin/index.html.

    Alle vorhandenen Vorlagen können auf diese Weise geändert werden, und ihre Namen und Strukturen finden Sie im Quellcode von Django .

  6. Jetzt können Sie die Vorlage entweder überschreiben, indem Sie sie von Grund auf neu schreiben, oder sie erweitern und dann bestimmte Blöcke überschreiben / erweitern.

    Wenn Sie beispielsweise alles so lassen möchten, wie es ist, aber den contentBlock überschreiben möchten (der auf der Indexseite die von Ihnen registrierten Apps und deren Modelle auflistet), fügen Sie Folgendes hinzu templates/admin/index.html:

    {% extends 'admin/index.html' %}
    
    {% block content %}
      <h1>
        Hello, {{ world }}!
      </h1>
    {% endblock %}

    Um den ursprünglichen Inhalt eines Blocks beizubehalten, fügen {{ block.super }}Sie hinzu, wo immer der ursprüngliche Inhalt angezeigt werden soll:

    {% extends 'admin/index.html' %}
    
    {% block content %}
      <h1>
        Hello, {{ world }}!
      </h1>
      {{ block.super }}
    {% endblock %}

    Sie können auch benutzerdefinierte Stile und Skripte hinzufügen, indem Sie die Blöcke extrastyleund extraheadändern.

Faheel
quelle
Haben Sie eine Quelle oder Dokumentation dazu?
Mary
Abgesehen von den beiden Referenzen, die ich in Punkt 5 hinzugefügt habe, nein, ich habe nichts anderes.
Faheel
1

Ich stimme Chris Pratt zu. Aber ich denke, es ist besser, den Symlink zum ursprünglichen Django-Ordner zu erstellen, in dem sich die Admin-Vorlagen befinden:

ln -s /usr/local/lib/python2.7/dist-packages/django/contrib/admin/templates/admin/ templates/django_admin

und wie Sie sehen können, hängt es von der Python-Version und dem Ordner ab, in dem der Django installiert wurde. In Zukunft oder auf einem Produktionsserver müssen Sie möglicherweise den Pfad ändern.

James May
quelle
0

Diese Seite hatte eine einfache Lösung, die mit meiner Django 1.7-Konfiguration funktionierte.

ZUERST : Erstellen Sie in der Vorlage / im Verzeichnis Ihres Projekts einen Symlink mit dem Namen admin_src zu Ihren installierten Django-Vorlagen. Für mich auf Dreamhost mit einer virtuellen Umgebung waren meine "Quell" -Django-Administratorvorlagen in:

~/virtualenvs/mydomain/lib/python2.7/site-packages/django/contrib/admin/templates/admin

ZWEITENS: Erstellen Sie ein Administratorverzeichnis in Vorlagen /

Die Vorlage / das Verzeichnis meines Projekts sah nun folgendermaßen aus:

/templates/
   admin
   admin_src -> [to django source]
   base.html
   index.html
   sitemap.xml
   etc...

DRITTE: Erstellen Sie in Ihrer neuen Vorlage / admin / ein Verzeichnis base.html mit folgendem Inhalt:

{% extends "admin_src/base.html" %}

{% block extrahead %}
<link rel='shortcut icon' href='{{ STATIC_URL }}img/favicon-admin.ico' />
{% endblock %}

VIERTE: Fügen Sie Ihre admin favicon-admin.ico in Ihren statischen root img Ordner hinzu.

Getan. Einfach.

mitchf
quelle
0

Fügen Sie diese Zeile für den App-Index zu einer allgemeinen Py-Datei wie url.py hinzu

admin.site.index_template = 'admin/custom_index.html'

für App-Modul-Index: Fügen Sie diese Zeile zu admin.py hinzu

admin.AdminSite.app_index_template = "servers/servers-home.html"

für Änderungsliste: Fügen Sie diese Zeile zur Admin-Klasse hinzu:

change_list_template = "servers/servers_changelist.html"

für Formularvorlage für App-Module: Fügen Sie diese Zeile Ihrer Admin-Klasse hinzu

change_form_template = "servers/server_changeform.html"

usw. und finden Sie andere in den Modulklassen des gleichen Administrators

Saurabh Chandra Patel
quelle
-1

Sie können django-overextends verwenden , das eine kreisförmige Vorlagenvererbung für Django bereitstellt.

Es stammt aus dem Mezzanine CMS, von wo Stephen es in eine eigenständige Django-Erweiterung extrahiert hat.

Weitere Informationen finden Sie unter "Überschreiben und Erweitern von Vorlagen" (http: /mezzanine.jupo.org/docs/content-architecture.html#overriding-vs-extending-templates) in den Mezzanine-Dokumenten.

Weitere Informationen finden Sie in Stephens Blog "Circular Template Inheritance for Django" (http: /blog.jupo.org/2012/05/17/circular-template-inheritance-for-django).

Und in Google Groups die Diskussion (https://groups.google.com/forum/ #! Topic / mezzanine-users / sUydcf_IZkQ), mit der die Entwicklung dieser Funktion gestartet wurde.

Hinweis:

Ich habe nicht den Ruf, mehr als 2 Links hinzuzufügen. Aber ich denke, die Links bieten interessante Hintergrundinformationen. Also habe ich nach "http (s):" einen Schrägstrich ausgelassen. Vielleicht kann jemand mit einem besseren Ruf die Links reparieren und diesen Hinweis entfernen.

Henri Hulski
quelle
Seit Django 1.9 war dieses Projekt nicht relevant, der Betreuer macht einfach keine Werbung dafür, siehe code.djangoproject.com/ticket/15053 und github.com/stephenmcd/django-overextends/pull/37 . Um die vollständige Kontrolle darüber zu übernehmen, aus welcher App eine Vorlage geladen wird, gibt es django-apptemplates und django-app-namespace-template-loader, die beide immer noch relevant sind, wenn Sie von einer App zur anderen erweitern möchten.
Benjaoming