Як переосмислити та розширити основні шаблони адміністратора Django?


126

Як змінити шаблон адміністратора (наприклад, admin / index.html), одночасно розширивши його (див. Https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing -an-admin-template )?

По-перше - я знаю, що на це запитання було задано і відповіли раніше (див. Django: Переосмислення та розширення шаблону програми ), але як йдеться у відповіді, воно не застосовується безпосередньо, якщо ви використовуєте завантажувач шаблонів app_directories (який є більшою частиною час).

Моє поточне вирішення полягає в тому, щоб зробити копії та поширити з них замість того, щоб поширюватись безпосередньо з шаблонів адміністратора. Це чудово працює, але це дуже заплутано і додає додаткової роботи, коли змінюються шаблони адміністратора.

Це може придумати певний розширений тег для шаблонів, але я не хочу винаходити колесо, якщо вже існує рішення.

Зі сторони: Хто-небудь знає, чи вирішить цю проблему сам Джанго?


1
Копіювання шаблонів адміністрування, їх розширення та переміщення / додавання блоків є найбільш ефективним, хоча й не оптимальним робочим процесом з огляду на поточний стан Джанго. Я не бачив іншого способу зробити те, що ви намагаєтеся зробити за три роки роботи з ним :)
Брендон,

Ну - я не знаю, добре це чи ні, але принаймні такі люди, як ти, дійшли такого ж висновку. Приємно чути. :)
Semmel

Відповіді:


101

Оновлення :

Прочитайте Документи для вашої версії Джанго. напр

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 -шаблони

Оригінальна відповідь від 2011 року:

У мене був такий самий випуск близько півтора років тому, і я знайшов приємний завантажувач шаблонів на djangosnippets.org, який робить це легко. Це дозволяє розширити шаблон у певному додатку, надаючи можливість створити власний адміністратор / index.html, який розширює шаблон адміністрування / index.html з програми адміністратора. Подобається це:

{% 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 %}

Я подав повний приклад того, як використовувати цей завантажувач шаблонів у публікації блогу на своєму веб-сайті.


18
Для довідки; відповідний фрагмент перетворений у додаток django і доступний у PyPi (pip / easy_install) як django-apptemplates: pypi.python.org/pypi/django-apptemplates
Romløk

9
Просто, щоб бути на 100% явним: вищевказане рішення НЕ БУДЕ ДІЛЬШЕ РОБОТИ для останніх версій Джанго (принаймні 1,4), оскільки одна з функцій, яку використовує сценарій, знецінюється. Ви можете знайти оновлене джерело тут
OldTinfoil

2
Зауважте, що з Django 1.8 це все одно буде працювати, але налаштування потрібно зробити спеціальним способом (див. Приклад налаштування app_names.Налаштування завантажувача ). django-app-namespace-template-loader також є робочою альтернативою, django-apptemplatesякщо він може припинити роботу одного дня.
Петерино

Ця відповідь була дуже хорошою для старих версій Джанго. Але на даний момент ще одна відповідь Ченга є більш актуальною. stackoverflow.com/a/29997719/7344164
SoftwareEnggUmar

70

Що стосується поточного випуску Django 1.8, немає необхідності здійснювати символьне посилання, копіювати адмін / шаблони у папку проекту або встановлювати середні продукти, як це запропоновано у відповідях вище. Ось що робити:

  1. створити таку структуру дерева (рекомендується офіційною документацією )

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

Примітка . Розташування цього файлу не важливо. Ви можете помістити його у свою програму, і вона все одно буде працювати. Поки джанго може виявити його місцезнаходження. Що ще важливіше, це те, що ім'я HTML-файлу має бути таким же, як оригінальне ім'я HTML-файлу, надане django.

  1. Додайте цей шлях до шаблону до свого 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. Визначте ім’я та блок, який ви хочете змінити. Це робиться, переглянувши каталог адміністраторів / шаблонів django. Я використовую virtualenv, тому для мене шлях тут:

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

У цьому прикладі я хочу змінити форму додавання нової користувача. Відповідним шаблоном для цього перегляду є change_form.html . Відкрийте change_form.html і знайдіть {% block%}, який потрібно розширити.

  1. У свою change_form.html напишіть такі речі:

    {% extends "admin/change_form.html" %}
    {% block field_sets %}
         {# your modification here #}
    {% endblock %}
  2. Завантажте свою сторінку, і ви повинні побачити зміни


Це все ще недостатньо для розширення основного шаблону "index.html", без копіювання всіх блоків. Рішення полягає в тому, щоб написати декілька ../шляху "exetends" і вказати оригінальний шлях більш унікальним {% extends "../../admin/templates/admin/index.html" %}. посилання на відповідь
hynekcer

1
Я думаю, що в TEMPLATES ми повинні використовувати "DIRS": [os.path.join (BASE_DIR, "шаблони")],
Рауль Рейес

Це тип нитки, який ідеально ілюструє недолік у SO. Рамка оновлюється, і питання вже не є актуальним, воно насправді стримує правильний шлях. Чудова відповідь тут. RTFM діти.
Дерек Адаїр

Дякую за цю відповідь. За винятком "Розташування цього файлу не важливо.", Все працювало чудово.
Манігундан Ясванта

54

якщо вам потрібно перезаписати admin/index.html, ви можете встановити параметр index_template для AdminSite.

напр

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

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

і розмістіть ваш шаблон <appname>/templates/admin/my_custom_index.html


5
Блискуче! Це дозволяє вам потім зробити {% extends "admin/index.html" %}з my_custom_index.html і мати посилання на шаблон адміністратора django, не копіюючи його. Дякую.
mattmc3

3
@Semmel повинен позначити це правильною відповіддю, оскільки це найпростіший підхід, який використовує вбудовані функції django і не вимагає використання користувальницьких завантажувачів шаблонів.
MrColes

17

За допомогою django1.5 (принаймні) ви можете визначити шаблон, який ви хочете використовувати для конкретноїmodeladmin

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

Можна зробити щось на кшталт

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

З change_form.htmlпростим розширенням шаблону HTML admin/change_form.html(чи ні, якщо ви хочете зробити це з нуля)


9

Відповідь Ченґса правильна, тому, як згідно з документами адміністратора, не кожен шаблон адміністратора може бути перезаписаний таким чином: https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#overriding-admin-templates

Шаблони, які можуть бути відмінені для програми чи моделі

Не кожен шаблон в contrib / admin / templates / admin може бути замінений на додаток або на модель. Можна:

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

Для тих шаблонів, які неможливо змінити таким чином, ви все одно можете їх замінити для всього проекту. Просто помістіть нову версію у свій каталог шаблонів / адміністратора . Це особливо корисно для створення нестандартних 404 та 500 сторінок

Мені довелося перезаписати login.html адміністратора, і тому довелося помістити переписаний шаблон у структуру цієї папки:

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

(без папки myapp в адміністраторі) Я не маю достатньої репутації, щоб коментувати публікацію Ченга, тому мені довелося написати це як нову відповідь.


Дякую за відгук Hyneker, я сподіваюся, що моя відповідь є чіткішою та прямо зараз.
matyas

Так, корисно знати, що шаблони можна налаштувати на рівні проекту, навіть якщо деякі з них можна змінити необов'язково на рівні програми.
hynekcer

5

Найкращий спосіб зробити це - помістити шаблони адміністрування Django всередині вашого проекту. Таким чином, ваші шаблони будуть у в templates/adminтой час, як шаблони адміністратора Django будуть сказати template/django_admin. Потім ви можете зробити щось на кшталт наступного:

templates / admin / change_form.html

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

Your stuff here

Якщо ви турбуєтесь про оновлення шаблонів запасів, ви можете включити їх із зовнішніми версіями svn або подібними.


Використання svn externals - чудова ідея. Проблема, яку ця проблема вводить, полягає в тому, що всі мої перекладачі збираються перекласти всі ці шаблони (оскільки makemessages збиратимуть рядки перекладу з усіх шаблонів адміністратора), що додасть багато додаткової роботи, якщо ви працюєте з декількома мовами. Можливо, є спосіб виключити ці шаблони з македемацій?
Semmel

Скористайтеся --ignoreаргументом з makemessages. Дивіться: docs.djangoproject.com/en/dev/ref/django-admin/#makemessages
Кріс Пратт

Я думаю, що інша відповідь краще відповідає моїй потребі. Але мені подобається ваше рішення і я думаю, що це хороша альтернатива, якщо ви не хочете возитися з вашими шаблонами-завантажувачами.
Semmel

5

Я не зміг знайти жодної відповіді або розділу в офіційних документах Django, які мали всю необхідну мені інформацію для переосмислення / розширення шаблонів адміністратора за замовчуванням, тому я пишу цю відповідь як повний посібник, сподіваючись, що це буде корисно для інших у майбутньому.

Припускаючи стандартну структуру проекту 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/

Ось що потрібно зробити:

  1. В mysite/admin.py, створити підклас 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()

    Переконайтеся в тому , щоб імпортувати custom_admin_siteв admin.pyваші програми та зареєструвати свої моделі на ньому , щоб відобразити їх на настроюється сайті адміністратора (якщо ви хочете).

  2. У mysite/apps.py, створіть підклас AdminConfigта встановіть default_siteйого admin.CustomAdminSiteз попереднього кроку:

    from django.contrib.admin.apps import AdminConfig
    
    
    class CustomAdminConfig(AdminConfig):
        default_site = 'admin.CustomAdminSite'
  3. В mysite/settings.py, замініть django.admin.siteв INSTALLED_APPSс apps.CustomAdminConfig(вашої призначеним для користувача адміністратором програми конфігурацією з попереднього кроку).

  4. У mysite/urls.py, замініть admin.site.urlsз адміністратора URL на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. Створіть шаблон, який ви хочете змінити у своєму templatesкаталозі, зберігаючи структуру каталогу каталогів шаблонів адміністратора Django за замовчуванням, як зазначено в документах . Наприклад, якщо ви змінювали admin/index.html, створіть файл templates/admin/index.html.

    Усі існуючі шаблони можна змінити таким чином, а їх назви та структури можна знайти у вихідному коді Джанго .

  6. Тепер ви можете або замінити шаблон, написавши його з нуля, або розширити його, а потім перезаписати / розширити конкретні блоки.

    Наприклад, якщо ви хотіли зберегти все як є, але хотіли б замінити contentблок (який на сторінці індексу перераховує додатки та їх моделі, які ви зареєстрували), додайте наступне до templates/admin/index.html:

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

    Щоб зберегти оригінальний вміст блоку, додайте, {{ block.super }}де ви хочете, щоб оригінальний вміст відображався:

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

    Ви також можете додавати власні стилі та сценарії, змінюючи блоки extrastyleта extrahead.


у вас є джерело чи документація щодо цього?
Марія

Крім двох посилань, які я додав у пункті 5, ні, нічого іншого я не маю.
Faheel

1

Я згоден з Крісом Праттом. Але я думаю, що краще створити симпосилання на оригінальну папку Django, де розміщуються шаблони адміністратора:

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

і як ви бачите, це залежить від версії python та папки, в якій встановлено Django. Тому в майбутньому або на виробничому сервері вам може знадобитися змінити шлях.


0

На цьому веб-сайті було просте рішення, яке працювало з моєю конфігурацією Django 1.7.

ПЕРШЕ: Створіть символьне посилання на ім’я admin_src у шаблоні / каталозі проекту до встановлених шаблонів Django. Для мене на Dreamhost, що використовує virtualenv, мої "джерельні" шаблони адміністратора Django були в:

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

ДРУГО: Створіть каталог адміністратора в шаблонах /

Отже, шаблон / каталог мого проекту тепер виглядав так:

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

ТРЕТИЙ: У новому шаблоні / адміністраторі / каталозі створіть файл base.html з таким вмістом:

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

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

ЧЕТВЕРТА: Додайте свого адміністратора favicon-admin.ico у свою статичну папку img.

Зроблено. Легко.


0

для індексу додатків додайте цей рядок до десь поширеного файла py, наприклад url.py

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

для індексу модуля програми: додайте цей рядок до admin.py

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

для списку змін: додайте цей рядок до класу адміністратора:

change_list_template = "servers/servers_changelist.html"

для шаблону форми модуля програми: додайте цей рядок у свій клас адміністратора

change_form_template = "servers/server_changeform.html"

тощо. та знайдіть інших у тих самих класах модулів адміністратора


-1

Ви можете використовувати django-overrextends , що забезпечує спадкове діловий шаблон для Django.

Він походить від Mezzanine CMS, звідки Стівен видобув його в окремий розширення Django.

Більше інформації ви можете знайти у розділі "Переосмислення та розширення шаблонів" (http: /mezzanine.jupo.org/docs/content-architecture.html#overriding-vs-extending-templates) у документах "Мецанін".

Більш глибокі нутрощі дивіться у блозі Стівенса "Спадкове циркулювання шаблону для Джанго" (http: /blog.jupo.org/2012/05/17/circular-template-inheritance-for-django).

А в групах Google обговорення (https: /groups.google.com/forum / #! Topic / mezzanine-users / sUydcf_IZkQ), яке розпочало розробку цієї функції.

Примітка:

У мене немає репутації додавати більше 2 посилань. Але я думаю, що посилання дають цікаву довідкову інформацію. Тому я просто залишив косу рису після "http (s):". Можливо, хтось із кращою репутацією може відремонтувати посилання та видалити цю примітку.


Оскільки Джанго 1.9, цей проект не був релевантним, сервіс просто не рекламує його, див. Code.djangoproject.com/ticket/15053 та github.com/stephenmcd/django-overextends/pull/37 . Для повного контролю над тим, з якого додатка завантажено шаблон, є django-apptemplates та django-app-namespace-template-loader, які обидва як і раніше актуальні, якщо ви хочете поширитись з одного додатка на інший.
benjaoming
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.