web-dev-qa-db-fra.com

Comment remplacer et étendre les modèles d'administration Django de base?

Comment remplacer un modèle d'administrateur (par exemple, admin/index.html) tout en l'étendant (voir https://docs.djangoproject.com/en/dev/ref/ref/contrib/admin/#overriding-vs -remplace-un-admin-template )?

Tout d’abord, je sais que cette question a déjà été posée et qu’on y a déjà répondu (voir Django: Ignorer ET étendre un modèle d’application ), mais comme le dit la réponse, elle n’est pas directement applicable si vous utilisez le est la plupart du temps).

Ma solution actuelle consiste à faire des copies et à les étendre au lieu de les étendre directement à partir des modèles d’administrateur. Cela fonctionne très bien, mais cela crée de la confusion et ajoute du travail supplémentaire lorsque les modèles d’administrateur changent.

Cela pourrait faire penser à une balise d'extension personnalisée pour les modèles, mais je ne veux pas réinventer la roue s'il existe déjà une solution.

Sur une note de côté: Est-ce que quelqu'un sait si ce problème sera résolu par Django lui-même?

97
Semmel

Mettre à jour

Lisez la documentation de votre version de Django. par exemple. 

https://docs.djangoproject.com/fr/1.11/ref/contrib/admin/#admin-overriding-templateshttps://docs.djangoproject.com/en/2.0/ref/contrib/admin/# admin-overriding-templates

Réponse originale de 2011:

J'ai eu le même problème il y a environ un an et demi et j'ai trouvé un chargeur de modèles Nice sur djangosnippets.org qui rend cela facile. Il vous permet d’étendre un modèle dans une application spécifique et de créer votre propre admin/index.html qui étend le modèle admin/index.html à partir de l’application admin. Comme ça:

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

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

J'ai donné un exemple complet sur la façon d'utiliser ce chargeur de modèles dans un article blog sur mon site Web.

93
heyman

En ce qui concerne Django 1.8 étant la version actuelle, il n'est pas nécessaire de créer un lien symbolique, de copier l'administrateur/les modèles dans votre dossier de projet ou d'installer des middlewares comme suggéré par les réponses ci-dessus. Voici ce qu'il faut faire:

  1. créer l'arborescence suivante (recommandée par le documentation officielle )

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

Note: l'emplacement de ce fichier n'est pas important. Vous pouvez le mettre dans votre application et cela fonctionnera toujours. Tant que son emplacement peut être découvert par Django. Plus important encore, le nom du fichier HTML doit être identique à celui du fichier HTML d'origine fourni par Django.

  1. Ajoutez ce chemin de modèle à votre settings.py:

    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. Identifiez le nom et le bloc que vous souhaitez remplacer. Ceci est fait en consultant le répertoire admin/templates de Django. J'utilise virtualenv, donc pour moi le chemin est ici:

    ~/.virtualenvs/Edge/lib/python2.7/site-packages/Django/contrib/admin/templates/admin
    

Dans cet exemple, je souhaite modifier le formulaire Ajouter un nouvel utilisateur. Le modèle responsable de cette vue est change_form.html. Ouvrez le fichier change_form.html et recherchez le {% block%} à étendre.

  1. Dans votre change_form.html, écrivez quelque chose comme ceci:

    {% extends "admin/change_form.html" %}
    {% block field_sets %}
         {# your modification here #}
    {% endblock %}
    
  2. Chargez votre page et vous devriez voir les changements

61
Cheng

si vous devez écraser le admin/index.html, vous pouvez définir le paramètre index_template de la AdminSite.

par exemple.

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

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

et placez votre modèle dans <appname>/templates/admin/my_custom_index.html

42
gingerlime

Avec Django 1.5 (au moins), vous pouvez définir le modèle que vous souhaitez utiliser pour une modeladmin particulière

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

Vous pouvez faire quelque chose comme

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

change_form.html étant un simple modèle html complétant admin/change_form.html (ou pas si vous voulez le faire à partir de zéro)

11
maazza

La meilleure façon de le faire est de placer les modèles d’administration Django dans votre projet. Ainsi, vos modèles seraient dans templates/admin tandis que les modèles d’administration Django d’origine seraient dans, par exemple, template/Django_admin. Ensuite, vous pouvez faire quelque chose comme ceci:

templates/admin/change_form.html

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

Your stuff here

Si vous souhaitez conserver les modèles de stock à jour, vous pouvez les inclure avec svn externals ou similaire.

5
Chris Pratt

Je suis d'accord avec Chris Pratt. Mais je pense qu'il est préférable de créer le lien symbolique vers le dossier Django d'origine dans lequel les modèles d'administration sont placés:

ln -s /usr/local/lib/python2.7/dist-packages/Django/contrib/admin/templates/admin/ templates/Django_admin

et comme vous pouvez le constater, cela dépend de la version de Python et du dossier d'installation de Django. Donc, à l'avenir ou sur un serveur de production, vous devrez peut-être modifier le chemin.

1
James May

pour app index ajouter cette ligne à un fichier py quelque part comme url.py

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

pour l'index du module d'application: ajoutez cette ligne à admin.py

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

pour la liste de modification: ajoutez cette ligne à la classe admin:

change_list_template = "servers/servers_changelist.html"

pour modèle de formulaire de module d'application: ajoutez cette ligne à votre classe d'administrateur

change_form_template = "servers/server_changeform.html"

etc. et trouvez-en d'autres dans les mêmes modules 

0

Ce site propose une solution simple qui fonctionne avec ma configuration Django 1.7.

FIRST: Créez un lien symbolique nommé admin_src dans le répertoire template/de votre projet avec vos modèles Django installés. Pour moi sur Dreamhost avec virtualenv, mes modèles d’administrateur Django "source" se trouvaient dans:

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

SECOND: Créez un répertoire admin dans templates /

Ainsi, le modèle/répertoire de mon projet ressemblait maintenant à ceci:

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

THIRD: Dans votre nouveau répertoire template/admin /, créez un fichier base.html avec ce contenu:

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

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

FOURTH: Ajoutez votre administrateur favicon-admin.ico dans votre dossier racine statique img.

Terminé. Facile.

0
mitchf

Vous pouvez utiliser Django-overextends , qui fournit un héritage de gabarit circulaire pour Django.

Il provient du CMS Mezzanine , d'où Stephen l'a extrait dans une extension autonome de Django.

Vous trouverez plus d’informations dans "Remplacer ou étendre les modèles" (http: /mezzanine.jupo.org/docs/content-architecture.html#overriding-vs-extending-templates) dans la documentation Mezzanine.

Pour de plus amples informations, consultez le blog Stephens "Héritage de modèles circulaires pour Django" (http: /blog.jupo.org/2012/05/17/circular-template-inheritance-for-Django).

Et dans Google Groupes, la discussion (https: /groups.google.com/forum/#! Topic/mezzanine-users/sUydcf_IZkQ) à l'origine du développement de cette fonctionnalité.

Remarque:

Je n'ai pas la réputation d'ajouter plus de 2 liens. Mais je pense que les liens fournissent des informations contextuelles intéressantes. Donc, je viens de laisser une barre oblique après "http (s):". Peut-être que quelqu'un avec une meilleure réputation peut réparer les liens et supprimer cette note.

0
Henri Hulski

Je ne pouvais pas trouver une seule réponse ou une section dans la documentation officielle de Django qui contenait all les informations dont j'avais besoin pour remplacer/étendre les modèles d'administration par défaut, aussi j'écris cette réponse sous forme de guide complet, en espérant que ce serait utile pour d'autres à l'avenir.

En supposant la structure standard du projet Django:

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/

Voici ce que vous devez faire:

  1. Dans mysite/admin.py, créez une sous-classe de 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()
    

    Assurez-vous d'importer custom_admin_site dans le admin.py de vos applications et enregistrez vos modèles dessus pour les afficher sur votre site d'administration personnalisé (si vous le souhaitez).

  2. Dans mysite/apps.py, créez une sous-classe de AdminConfig et définissez default_site sur admin.CustomAdminSite à partir de l'étape précédente:

    from Django.contrib.admin.apps import AdminConfig
    
    
    class CustomAdminConfig(AdminConfig):
        default_site = 'admin.CustomAdminSite'
    
  3. Dans mysite/settings.py, remplacez Django.admin.site dans INSTALLED_APPS par apps.CustomAdminConfig (votre configuration d'application admin personnalisée à l'étape précédente).

    from Django.contrib.admin.apps import AdminConfig
    
    
    class CustomAdminConfig(AdminConfig):
        default_site = 'admin.CustomAdminSite'
    
  4. Dans mysite/urls.py, remplacez admin.site.urls de l'URL d'administration par custom_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. Créez le modèle que vous souhaitez modifier dans votre répertoire templates, en conservant la structure de répertoire par défaut des modèles d’administration Django telle que spécifiée dans docs . Par exemple, si vous modifiez admin/index.html, créez le fichier templates/admin/index.html.

    Tous les modèles existants peuvent être modifiés de cette façon, et leurs noms et structures se trouvent dans le code source de Django .

  6. Vous pouvez maintenant remplacer le modèle en l'écrivant à partir de rien ou l'étendre, puis remplacer/étendre des blocs spécifiques.

    Par exemple, si vous souhaitez tout conserver tel quel mais que vous souhaitez remplacer le bloc content (qui, sur la page d'index, répertorie les applications et leurs modèles que vous avez enregistrés), ajoutez ce qui suit à templates/admin/index.html:

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

    Pour conserver le contenu d'origine d'un bloc, ajoutez {{ block.super }} à l'endroit où vous souhaitez afficher le contenu d'origine:

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

    Vous pouvez également ajouter des styles et des scripts personnalisés en modifiant les blocs extrastyle et extrahead.

0
Faheel Ahmad