How to override and extend basic Django admin templates?

前端 未结 11 852
长发绾君心
长发绾君心 2020-11-22 14:11

How do I override an admin template (e.g. admin/index.html) while at the same time extending it (see https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-r

相关标签:
11条回答
  • 2020-11-22 14:23

    if you need to overwrite the admin/index.html, you can set the index_template parameter of the AdminSite.

    e.g.

    # urls.py
    ...
    from django.contrib import admin
    
    admin.site.index_template = 'admin/my_custom_index.html'
    admin.autodiscover()
    

    and place your template in <appname>/templates/admin/my_custom_index.html

    0 讨论(0)
  • 2020-11-22 14:24

    As for Django 1.8 being the current release, there is no need to symlink, copy the admin/templates to your project folder, or install middlewares as suggested by the answers above. Here is what to do:

    1. create the following tree structure(recommended by the official documentation)

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

    Note: The location of this file is not important. You can put it inside your app and it will still work. As long as its location can be discovered by django. What's more important is the name of the HTML file has to be the same as the original HTML file name provided by django.

    1. Add this template path to your 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. Identify the name and block you want to override. This is done by looking into django's admin/templates directory. I am using virtualenv, so for me, the path is here:

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

    In this example, I want to modify the add new user form. The template responsiblve for this view is change_form.html. Open up the change_form.html and find the {% block %} that you want to extend.

    1. In your change_form.html, write somethings like this:

      {% extends "admin/change_form.html" %}
      {% block field_sets %}
           {# your modification here #}
      {% endblock %}
      
    2. Load up your page and you should see the changes

    0 讨论(0)
  • 2020-11-22 14:29

    Update:

    Read the Docs for your version of Django. e.g.

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

    Original answer from 2011:

    I had the same issue about a year and a half ago and I found a nice template loader on djangosnippets.org that makes this easy. It allows you to extend a template in a specific app, giving you the ability to create your own admin/index.html that extends the admin/index.html template from the admin app. Like this:

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

    I've given a full example on how to use this template loader in a blog post on my website.

    0 讨论(0)
  • 2020-11-22 14:32

    With django 1.5 (at least) you can define the template you want to use for a particular modeladmin

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

    You can do something like

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

    With change_form.html being a simple html template extending admin/change_form.html (or not if you want to do it from scratch)

    0 讨论(0)
  • 2020-11-22 14:34

    The best way to do it is to put the Django admin templates inside your project. So your templates would be in templates/admin while the stock Django admin templates would be in say template/django_admin. Then, you can do something like the following:

    templates/admin/change_form.html

    {% extends 'django_admin/change_form.html' %}
    
    Your stuff here
    

    If you're worried about keeping the stock templates up to date, you can include them with svn externals or similar.

    0 讨论(0)
  • 2020-11-22 14:35

    I couldn't find a single answer or a section in the official Django docs that had all the information I needed to override/extend the default admin templates, so I'm writing this answer as a complete guide, hoping that it would be helpful for others in the future.

    Assuming the standard Django project structure:

    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/
    

    Here's what you need to do:

    1. In mysite/admin.py, create a sub-class of 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()
      

      Make sure to import custom_admin_site in the admin.py of your apps and register your models on it to display them on your customized admin site (if you want to).

    2. In mysite/apps.py, create a sub-class of AdminConfig and set default_site to admin.CustomAdminSite from the previous step:

      from django.contrib.admin.apps import AdminConfig
      
      
      class CustomAdminConfig(AdminConfig):
          default_site = 'admin.CustomAdminSite'
      
    3. In mysite/settings.py, replace django.admin.site in INSTALLED_APPS with apps.CustomAdminConfig (your custom admin app config from the previous step).

    4. In mysite/urls.py, replace admin.site.urls from the admin URL to 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. Create the template you want to modify in your templates directory, maintaining the default Django admin templates directory structure as specified in the docs. For example, if you were modifying admin/index.html, create the file templates/admin/index.html.

      All of the existing templates can be modified this way, and their names and structures can be found in Django's source code.

    6. Now you can either override the template by writing it from scratch or extend it and then override/extend specific blocks.

      For example, if you wanted to keep everything as-is but wanted to override the content block (which on the index page lists the apps and their models that you registered), add the following to templates/admin/index.html:

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

      To preserve the original contents of a block, add {{ block.super }} wherever you want the original contents to be displayed:

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

      You can also add custom styles and scripts by modifying the extrastyle and extrahead blocks.

    0 讨论(0)
提交回复
热议问题