web-dev-qa-db-ja.com

基本的なDjango管理テンプレートをオーバーライドおよび拡張する方法

Adminテンプレート(例:admin/index.html)をオーバーライドすると同時にオーバーライドする方法( https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overridingを参照) -vs-replacing-an-admin-template )?

最初に-この質問は以前に尋ねられて回答されたことを知っています( Django:アプリテンプレートのオーバーライドと拡張 を参照してください)が、答えはapp_directoriesテンプレートを使用している場合は直接適用できないローダー(ほとんどの場合)。

私の現在の回避策は、管理者テンプレートから直接拡張するのではなく、コピーを作成してそこから拡張することです。これはうまく機能しますが、本当に混乱を招き、管理用テンプレートが変更されたときに余分な作業が追加されます。

テンプレートのカスタム拡張タグを考えることもできますが、既に解決策が存在する場合は、車輪を再発明したくありません。

補足:この問題がDjango自体によって対処されるかどうかは誰にもわかりませんか?

108
Semmel

更新

ご使用のバージョンのDjangoのドキュメントをご覧ください。例えば.

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

2011年の元の回答:

私は1年半前に同じ問題を抱えていましたが、これを簡単にするニース djangosnippets.orgのテンプレートローダー を見つけました。特定のアプリでテンプレートを拡張して、admin/indexを拡張する独自のadmin/index.htmlを作成することができます。管理アプリからのhtmlテンプレート。このような:

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

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

私のウェブサイトの ブログ投稿 でこのテンプレートローダーを使用する方法の完全な例を示しました。

97
heyman

現在のリリースであるDjango 1.8については、上記の回答で提案されているように、シンボリックリンクを作成したり、プロジェクトフォルダーにadmin/templatesをコピーしたり、ミドルウェアをインストールしたりする必要はありません。対処方法は次のとおりです。

  1. 次のツリー構造を作成します( 公式ドキュメント で推奨)

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

:このファイルの場所は重要ではありません。あなたはそれをあなたのアプリの中に置くことができ、それはまだ機能します。 Djangoがその場所を発見できる限り。さらに重要なのは、HTMLファイルの名前がDjangoによって提供される元のHTMLファイル名と同じでなければならないことです。

  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のadmin/templatesディレクトリを調べることで実行されます。私は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. ページをロードすると、変更が表示されるはずです

65
Cheng

admin/index.htmlを上書きする必要がある場合は、AdminSiteの-​​ index_template パラメーターを設定できます。

例えば.

# 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に配置します

44
gingerlime

Django 1.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.htmladmin/change_form.htmlを拡張する単純なhtmlテンプレートであること(または最初からやりたい場合はそうではありません)

15
maazza

Chengsの答えは正しいです。しかし、管理者ドキュメントによると、すべての管理者テンプレートをこの方法で上書きできるわけではありません。 https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#overriding-admin-テンプレート

アプリまたはモデルごとにオーバーライドできるテンプレート

Contrib/admin/templates/admin内のすべてのテンプレートがアプリごとまたはモデルごとにオーバーライドされるわけではありません。次のことができます。

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

この方法でオーバーライドできないテンプレートについては、プロジェクト全体でテンプレートをオーバーライドできます。新しいバージョンをtemplates/adminディレクトリに配置するだけですplace。これは、カスタム404ページと500ページを作成するのに特に便利です

管理者のlogin.htmlを上書きする必要があったため、上書きされたテンプレートをこのフォルダー構造に配置する必要がありました。

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

(管理者のmyappサブフォルダーなし)Chengの投稿にコメントするのに十分な評判がありません。これが新しい答えとしてこれを書かなければならなかった理由です。

7
matyas

最適な方法は、プロジェクト内にDjango管理テンプレートを配置することです。したがって、テンプレートはtemplates/adminにあり、ストックDjango adminテンプレートはtemplate/Django_adminにあります。その後、次のようなことができます。

templates/admin/change_form.html

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

Your stuff here

在庫テンプレートを最新の状態に保つことが心配な場合は、svn externalsまたは同様のものでそれらを含めることができます。

5
Chris Pratt

公式のDjangoドキュメントで、オーバーライドするために必要な情報allを含む単一の回答またはセクションを見つけることができませんでした。デフォルトの管理テンプレートを拡張して、この回答を完全なガイドとして作成し、将来他の人にとって役立つことを願っています。

標準の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_siteadmin.pyをインポートし、モデルを登録して、カスタマイズした管理サイトに表示します(必要な場合)。

  2. mysite/apps.pyで、AdminConfigのサブクラスを作成し、前の手順でdefault_siteadmin.CustomAdminSiteに設定します。

    from Django.contrib.admin.apps import AdminConfig
    
    
    class CustomAdminConfig(AdminConfig):
        default_site = 'admin.CustomAdminSite'
    
  3. mysite/settings.pyで、Django.admin.siteINSTALLED_APPSapps.CustomAdminConfig(前の手順で作成したカスタム管理アプリの構成)に置き換えます。

  4. mysite/urls.pyで、管理URLのadmin.site.urlscustom_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. docs で指定されているデフォルトのDjango adminテンプレートのディレクトリ構造を維持しながら、変更するテンプレートをtemplatesディレクトリに作成します。たとえば、admin/index.htmlを変更する場合は、ファイルtemplates/admin/index.htmlを作成します。

    既存のテンプレートはすべてこの方法で変更でき、その名前と構造は Djangoのソースコード にあります。

  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ブロックを変更して、カスタムスタイルとスクリプトを追加することもできます。

2
Faheel Ahmad

クリス・プラットに同意します。しかし、管理テンプレートが配置される元のDjangoフォルダーへのシンボリックリンクを作成する方が良いと思います:

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

ご覧のとおり、pythonバージョンとDjangoがインストールされているフォルダーに依存します。そのため、将来または本番サーバーで、パスを変更する必要がある場合があります。

1
James May

アプリインデックスの場合、url.pyなどの一般的な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"

など。同じ管理者のモジュールクラスで他を見つける

This サイトには、私のDjango 1.7構成で動作する簡単なソリューションがありました。

FIRST:プロジェクトのtemplate /ディレクトリに、インストール済みのDjangoテンプレートへのadmin_srcという名前のシンボリックリンクを作成します。 virtualenvを使用するDreamhostの場合、「ソース」Django管理テンプレートは次の場所にありました。

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

SECOND:templates /にadminディレクトリを作成します

したがって、私のプロジェクトのtemplate /ディレクトリは次のようになりました。

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

THIRD:新しいtemplate/admin /ディレクトリに、このコンテンツを含むbase.htmlファイルを作成します。

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

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

FOURTH:admin favicon-admin.icoを静的ルートimgフォルダーに追加します。

できた簡単です。

0
mitchf

Django-overextends を使用できます。これは、Djangoの循環テンプレート継承を提供します。

これは Mezzanine CMSに由来し、StephenはそれをスタンドアロンDjango拡張に抽出しました。

詳細については、メザニンドキュメント内の「テンプレートのオーバーライドと拡張」(http:/mezzanine.jupo.org/docs/content-architecture.html#overriding-vs-extending-templates)をご覧ください。

詳細については、Stephensのブログ「Djangoの円形テンプレート継承」(http:/blog.jupo.org/2012/05/17/circular-template-inheritance-for-Django)をご覧ください。

また、Googleグループでは、この機能の開発を開始したディスカッション(https:/groups.google.com/forum /#!topic/mezzanine-users/sUydcf_IZkQ)。

注意:

3つ以上のリンクを追加する評判はありません。しかし、リンクは興味深い背景情報を提供すると思います。そのため、「http(s):」の後にスラッシュを付けませんでした。評判の良い誰かがリンクを修復し、このメモを削除することができます。

0
Henri Hulski