Як переосмислити та розширити основні шаблони адміністратора 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.