기본 Django 관리 템플릿을 재정의하고 확장하는 방법은 무엇입니까?


126

관리자 템플릿 (예 : admin / index.html)을 확장하면서 동시에 재정의하는 방법 ( https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing 참조) -an-admin-template )?

첫째-이 질문이 이전에 묻고 답한 적이 있다는 것을 알고 있지만 ( Django : 앱 템플릿 재정의 및 확장 참조 ) 대답에서 알 수 있듯이 app_directories 템플릿 로더를 사용하는 경우에는 직접 적용 할 수 없습니다 (대부분의 시각).

현재 해결 방법은 관리 템플릿에서 직접 확장하는 대신 복사본을 만들고 확장하는 것입니다. 이것은 훌륭하게 작동하지만 정말 혼란스럽고 관리 템플릿이 변경되면 추가 작업이 추가됩니다.

템플릿에 대한 사용자 지정 확장 태그를 생각할 수 있지만 이미 솔루션이있는 경우 바퀴를 재발 명하고 싶지 않습니다.

참고 :이 문제가 Django 자체에서 해결되는지 아는 사람이 있습니까?


1
관리자 템플릿을 복사하고 확장하고 블록을 재정의 / 추가하는 것이 가장 효율적이지만 Django의 현재 상태를 고려할 때 최적의 워크 플로는 아닙니다. 3 년 동안 당신이하려는 일을 할 수있는 다른 방법은 본 적이 없습니다. :)
Brandon

글쎄-이것이 좋은 것인지 아닌지는 모르겠지만 적어도 당신 같은 사람들은 같은 결론에 도달했습니다. 좋은 소식입니다. :)
Semmel 2011-07-05

답변:


101

업데이트 :

사용중인 Django 버전에 대한 문서를 읽어보세요. 예 :

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 년의 원래 답변 :

약 1 년 반 전에 같은 문제가 있었는데 djangosnippets.org 에서이 작업을 쉽게 할 수있는 멋진 템플릿 로더를 찾았습니다 . 특정 앱에서 템플릿을 확장 할 수 있으므로 관리자 앱에서 admin / index.html 템플릿을 확장하는 고유 한 admin / 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
참고로; 문제의 조각은 장고 응용 프로그램으로 전환하고, 장고 - apptemplates로 (PIP / easy_install을) PyPi에서 사용할 수있다 : pypi.python.org/pypi/django-apptemplates을
Romløk

9
100 % 명시 적으로 말하면 위의 솔루션은 최신 버전의 Django (최소 1.4)에서 더 이상 작동하지 않습니다. 스크립트에서 사용하는 함수 중 하나가 감가 상각되기 때문입니다. 여기에서 업데이트 된 소스를 찾을 수 있습니다
OldTinfoil 2013 년

2
Django 1.8에서도 여전히 작동하지만 설정은 특별한 방법으로 이루어져야 합니다 (예로 app_namespace.Loader 설정 참조 ). django-app-namespace-template-loaderdjango-apptemplates언젠가 작동을 멈출 수있는 경우 에도 작동하는 대안 입니다.
Peterino

이 답변은 이전 Django 버전에서 매우 좋았습니다. 그러나 현재로서는 Cheng의 또 다른 답변이 더 관련이 있습니다. 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 파일의 이름이 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. 페이지를로드하면 변경 사항이 표시됩니다.


모든 블록을 복사하지 않고 기본 "index.html"템플릿을 확장하는 것으로는 충분하지 않습니다. 해결책은 ../"exetends"경로에 일부를 작성 하고 원래 경로를보다 고유하게 지정하는 것 {% extends "../../admin/templates/admin/index.html" %}입니다. 대답 링크
hynekcer

1
TEMPLATES에서는 'DIRS'를 사용해야한다고 생각합니다. [os.path.join (BASE_DIR, 'templates')],
Raul Reyes

이것은 SO의 결함을 완벽하게 보여주는 스레드 유형입니다. 프레임 워크가 업데이트되고 질문은 더 이상 관련이 없습니다. 사실 적절한 경로를 방해하는 것입니다. 여기에 좋은 대답입니다. RTFM 아이들.
Derek Adair 2013 년

이 답변에 감사드립니다. "이 파일의 위치는 중요하지 않습니다."를 제외하고 모든 것이 훌륭하게 작동했습니다.
Jaswanth Manigundan

54

을 덮어 써야하는 경우 admin/index.htmlindex_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은 내장 된 장고 기능을 사용하고 사용자 정의 템플릿 로더를 사용할 필요가없는 가장 간단한 접근 방식이므로이를 정답으로 표시해야합니다.
MrColes

17

으로 django당신은 당신이 특정에 사용할 템플릿을 정의 할 수 있습니다 (적어도) 1.5modeladmin

참조 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

Chengs의 대답은 정확합니다. 관리자 문서에 따르면 모든 관리자 템플릿을 다음과 같이 덮어 쓸 수있는 것은 아닙니다 : 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

사람들을 위해 재정의 할 수 없습니다 템플릿 이 방법으로, 당신은 여전히 전체 프로젝트를 오버라이드 (override) 할 수 있습니다. 그냥 배치 당신의 새로운 버전을 템플릿 / 관리자 디렉토리. 이것은 사용자 지정 404 및 500 페이지를 만드는 데 특히 유용합니다.

관리자의 login.html을 덮어 써야했기 때문에 덮어 쓴 템플릿을 다음 폴더 구조에 넣어야했습니다.

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

(관리자에 myapp 하위 폴더가 없음) Cheng의 게시물에 댓글을 달기에 충분한 평판이 없기 때문에 이것을 새로운 답변으로 작성해야했습니다.


피드백 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 externals 또는 이와 유사한 템플릿을 포함 할 수 있습니다.


svn 외부를 사용하는 것은 좋은 생각입니다. 이로 인해 발생하는 문제는 모든 번역가가 모든 템플릿을 번역한다는 것입니다 (makemessages는 모든 관리 템플릿에서 번역 문자열을 수집하기 때문에). 여러 언어로 작업하는 경우 많은 추가 작업이 추가됩니다. makemessages에서 해당 템플릿을 제외하는 방법이 있습니까?
Semmel

사용 --ignore에 인수를 makemessages. 참조 : docs.djangoproject.com/en/dev/ref/django-admin/#makemessages
Chris Pratt

다른 답변이 내 필요에 더 잘 맞는 것 같습니다. 그러나 나는 당신의 솔루션을 좋아하고 템플릿 로더를 엉망으로 만들고 싶지 않다면 좋은 대안이라고 생각합니다.
Semmel 2011

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.siteINSTALLED_APPSapps.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. docs에templates 지정된 기본 Django 관리 템플릿 디렉터리 구조를 유지하면서 디렉터리 에서 수정할 템플릿을 만듭니다 . 예를 들어를 수정 하는 경우 파일을 만듭니다 .admin/index.htmltemplates/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 %}

    extrastyleextrahead블록 을 수정하여 사용자 스타일과 스크립트를 추가 할 수도 있습니다 .


이에 대한 소스 또는 문서가 있습니까?
Mary

5 번에서 추가 한 두 가지 참고 문헌 외에는 다른 것이 없습니다.
Faheel

1

나는 Chris Pratt에 동의합니다. 하지만 관리 템플릿이있는 원본 Django 폴더에 대한 심볼릭 링크를 만드는 것이 더 낫다고 생각합니다.

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

보시다시피 Python 버전과 Django가 설치된 폴더에 따라 다릅니다. 따라서 향후 또는 프로덕션 서버에서 경로를 변경해야 할 수도 있습니다.


0

사이트에는 Django 1.7 구성과 함께 작동하는 간단한 솔루션이 있습니다.

첫 번째 : 프로젝트의 template / 디렉토리에 설치된 Django 템플릿에 대한 이름이 admin_src 인 심볼릭 링크를 만듭니다 . virtualenv를 사용하는 Dreamhost에서 저의 "소스"Django 관리 템플릿은 다음 위치에있었습니다.

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

두 번째 : templates /에 관리자 디렉터리 생성

따라서 내 프로젝트의 template / 디렉토리는 다음과 같습니다.

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

셋째 : 새 template / admin / 디렉토리 에서 다음 내용으로 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

앱 색인의 경우이 줄을 url.py와 같은 일반적인 py 파일에 추가하십시오.

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

for app module index :이 줄을 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에 대한 순환 템플릿 상속을 제공 하는 django-overextends를 사용할 수 있습니다 .

그것은에서 온다 메 자닌 스티븐 독립 장고 확장으로 압축을 푼 곳에서, CMS.

Mezzanine 문서 내의 "Overriding vs Extending Templates"(http : /mezzanine.jupo.org/docs/content-architecture.html#overriding-vs-extending-templates)에서 더 많은 정보를 찾을 수 있습니다.

자세한 내용은 Stephens 블로그 "Circular Template Inheritance for Django"(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) :"뒤에 슬래시를 생략했습니다. 평판이 더 좋은 사람이 링크를 복구하고이 메모를 제거 할 수 있습니다.


Django 1.9 이후로이 프로젝트는 관련이 없었고 유지 관리자는 광고하지 않습니다 . code.djangoproject.com/ticket/15053github.com/stephenmcd/django-overextends/pull/37을 참조하십시오 . 템플릿이로드되는 앱을 완전히 제어하기 위해 django-apptemplates 및 django-app-namespace-template-loader가 있습니다. 둘 다 한 앱에서 다른 앱으로 확장하려는 경우 여전히 관련이 있습니다.
benjaoming
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.