如何覆盖和扩展基本的 Django 管理模板?

2024-12-27 08:47:00
admin
原创
110
摘要:问题描述:如何覆盖管理模板(例如 admin/index.html)同时扩展它(请参阅https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing-an-admin-template)?首先 - 我知道这个问题...

问题描述:

如何覆盖管理模板(例如 admin/index.html)同时扩展它(请参阅https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing-an-admin-template)?

首先 - 我知道这个问题之前已经被问过并回答过(请参阅Django:覆盖和扩展应用程序模板),但正如答案所说,如果你使用app_directories模板加载器(大多数情况下),它并不直接适用。

我目前的解决方法是复制并从中扩展,而不是直接从管理模板中扩展。这种方法效果很好,但确实很混乱,而且当管理模板更改时会增加额外的工作。

它可以考虑为模板提供一些自定义的扩展标签,但如果已经存在解决方案,我就不想重新发明轮子。

附注:有人知道 Django 本身是否会解决这个问题吗?


解决方案 1:

更新

阅读你所用Django版本的文档,例如最新版本或旧LTS版本 :3.2、2.2、1.11

2011 年的原始答案:

大约一年半前,我遇到过同样的问题,后来我在 djangosnippets.org 上找到了一个不错的模板加载器,可以简化这个问题。它允许您扩展特定应用程序中的模板,使您能够创建自己的admin/index.html,从而扩展管理应用程序中的 admin/index.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 %}

我已经在我的网站的博客文章中给出了如何使用此模板加载器的完整示例。

解决方案 2:

由于 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',
            ],
        },
    },
]
  1. 确定要覆盖的名称和块。这可以通过查看 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 %}
  1. 加载你的页面,你应该会看到变化

解决方案 3:

如果需要覆盖admin/index.html,可以设置的index_templateAdminSite参数。

例如

# 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

解决方案 4:

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(或者如果你想从头开始做的话)

解决方案 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并在其中注册您的模型,以便在您的自定义管理网站上显示它们(如果您愿意)。

  1. 在 中mysite/apps.py,创建 的子类AdminConfig,并根据上一步将其设置default_site为:admin.CustomAdminSite

from django.contrib.admin.apps import AdminConfig


class CustomAdminConfig(AdminConfig):
    default_site = 'admin.CustomAdminSite'
  1. 在 中mysite/settings.py,将 替换django.admin.siteINSTALLED_APPSapps.CustomAdminConfig上一步中的自定义管理应用程序配置)。

  2. 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)),
    ...
]
  1. 在目录中创建要修改的模板,并维护文档templates中指定的默认 Django 管理模板目录结构。例如,如果您要修改,请创建文件。admin/index.html`templates/admin/index.html`

所有现有的模板都可以通过这种方式修改,它们的名称和结构可以在Django的源代码中找到。

  1. 现在,您可以通过从头开始编写来覆盖模板,或者扩展它,然后覆盖/扩展特定的块。

例如,如果您希望保持一切原样,但又想覆盖该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块来添加自定义样式和脚本。

解决方案 6:

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

对于无法通过这种方式覆盖的模板,您仍然可以为整个项目覆盖它们。只需新版本放在templates/admin目录中即可。这对于创建自定义 404 和 500 页面特别有用

我必须覆盖管理员的 login.html,因此必须将覆盖的模板放在这个文件夹结构中:

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

(没有管理员中的 myapp 子文件夹)我没有足够的声誉来评论 Cheng 的帖子,这就是我不得不将其写为新答案的原因。

解决方案 7:

最好的方法是将 Django 管理模板放入您的项目中。这样您的模板就会在,templates/admin而普通的 Django 管理模板则会在template/django_admin。然后,您可以执行以下操作:

模板/管理员/change_form.html

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

Your stuff here

如果您担心保持库存模板保持最新,您可以将它们包含在 svn externals 或类似程序中。

解决方案 8:

对于应用程序索引,请将这一行添加到某个常见的 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"

等,并在同一个管理员的模块类中找到其他

解决方案 9:

您可以通过多种方式覆盖 django 管理模板。

例如django-project如下图所示:

django-project
 |-core
 |  └-settings.py
 |-app1
 |  |-models.py
 |  └-admin.py
 |-app2
 └-templates

然后,BASE_DIR / 'templates'设置为DIRSTEMPLATES以便settings.py文件templates夹被识别,如下所示:

# "core/settings.py"

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            BASE_DIR / 'templates', # Here
        ],
        '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',
            ],
        },
    },
]

并且,有FoodDrink型号如下app1/models.py图所示:

# "app1/models.py"

class Food(models.Model):
    name = models.CharField(max_length=20)

class Drink(models.Model):
    name = models.CharField(max_length=20)

并且,有FoodDrink管理员,app1/admin.py如下所示:

# "app1/admin.py"

@admin.register(Food)
class FoodAdmin(admin.ModelAdmin):
    pass

@admin.register(Drink)
class DrinkAdmin(admin.ModelAdmin):
    pass

现在,您可以覆盖、和中的其中一个 django 管理模板change_form.html ,如下所示。 *您可以从虚拟环境中复制django管理模板,并且某些 django 管理模板无法在或中被覆盖,但这些 django 管理模板可以在、和中全部覆盖,您可以看到我的回答,其中解释了哪些 django 管理模板可以在哪些目录中被覆盖。templates/admin/`templates/admin/app1/templates/admin/app1/food/django/contrib/admin/templates/admin/templates/admin/app1/templates/admin/app1/food/templates/admin/templates/admin/app1/`templates/admin/app1/food/

change_form.html下面的templates/admin/可以自动应用于所有应用程序中的所有管理员。 *小写的文件夹名称admin可以正常工作:

django-project
 |-core
 |  └-settings.py
 |-app1
 |  |-models.py
 |  └-admin.py
 |-app2
 └-templates
    └-admin
       └-change_form.html # Here

change_form.html下面的templates/admin/app1/可以自动应用于 中的所有管理员app1。 *小写的文件夹名称app1可以正常工作:

django-project
 |-core
 |  └-settings.py
 |-app1
 |  |-models.py
 |  └-admin.py
 |-app2
 └-templates
    └-admin
       |-app1
       |  └-change_form.html # Here
       └-app2

change_form.html下面的templates/admin/app1/food/可以自动应用到food中的管理员app1。 *小写的文件夹名称food可以正常工作:

django-project
 |-core
 |  └-settings.py
 |-app1
 |  |-models.py
 |  └-admin.py
 |-app2
 └-templates
    └-admin
       |-app1
       |  |-food
       |  |  └-change_form.html # Here
       |  └-drink
       └-app2

现在,您可以重命名,但任何文件夹中的重命名change_form.htmlcustom_change_form.html无法custom_change_form.html自动应用于任何应用程序中的任何管理员。因此,您需要手动应用于custom_change_form.html您想要应用custom_change_form.html的任何应用程序中的任何管理员。

custom_change_form.html如下所示templates/admin/

django-project
 |-core
 |  └-settings.py
 |-app1
 |  |-models.py
 |  └-admin.py
 |-app2
 └-templates
    └-admin
       └-custom_change_form.html # Here

设置admin/custom_change_form.html为change_form_template和admins 如下所示。 *您可以找到更多自Food定义模板选项:Drink

# "app1/admin.py"

@admin.register(Food)
class FoodAdmin(admin.ModelAdmin):
    change_form_template = 'admin/custom_change_form.html'

@admin.register(Drink)
class DrinkAdmin(admin.ModelAdmin):
    change_form_template = 'admin/custom_change_form.html'

custom_change_form.html如下所示templates/admin/app1/

django-project
 |-core
 |  └-settings.py
 |-app1
 |  |-models.py
 |  └-admin.py
 |-app2
 └-templates
    └-admin
       |-app1
       |  └-custom_change_form.html # Here
       └-app2

设置admin/app1/custom_change_form.htmlchange_form_templateinFoodDrinkadmins如下图所示:

# "app1/admin.py"

@admin.register(Food)
class FoodAdmin(admin.ModelAdmin):
    change_form_template = 'admin/app1/custom_change_form.html'

@admin.register(Drink)
class DrinkAdmin(admin.ModelAdmin):
    change_form_template = 'admin/app1/custom_change_form.html'

custom_change_form.html如下所示templates/admin/app1/food

django-project
 |-core
 |  └-settings.py
 |-app1
 |  |-models.py
 |  └-admin.py
 |-app2
 └-templates
    └-admin
       |-app1
       |  |-food
       |  |  └-custom_change_form.html # Here
       |  └-drink
       └-app2

设置admin/app1/food/custom_change_form.htmlchange_form_templateinFoodDrinkadmins如下图所示:

# "app1/admin.py"

@admin.register(Food)
class FoodAdmin(admin.ModelAdmin):
    change_form_template = 'admin/app1/food/custom_change_form.html'

@admin.register(Drink)
class DrinkAdmin(admin.ModelAdmin):
    change_form_template = 'admin/app1/food/custom_change_form.html'

解决方案 10:

我同意 Chris Pratt 的观点。但我认为最好创建指向管理模板所在的原始 Django 文件夹的符号链接:

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

如您所见,它取决于 Python 版本和 Django 安装的文件夹。因此,将来或在生产服务器上,您可能需要更改路径。

解决方案 11:

站点有一个简单的解决方案,适用于我的 Django 1.7 配置。

首先:在项目的 template/ 目录中创建一个名为admin_src的符号链接,指向已安装的 Django 模板。对于我在 Dreamhost 上使用虚拟环境的我来说,我的“源”Django 管理模板位于:

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

第二:在 templates/ 中创建一个管理目录

所以我的项目的模板/目录现在看起来像这样:

/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 文件夹中。

完成。简单。

解决方案 12:

您可以使用django-overextends,它为 Django 提供循环模板继承。

它来自Mezzanine CMS,Stephen 将其提取到独立的 Django 扩展中。

您可以在 Mezzanine 文档中的“覆盖与扩展模板”(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 Groups 中,讨论了(https:/groups.google.com/forum/#!topic/mezzanine-users/sUydcf_IZkQ)该功能的开发。

笔记:

我的声誉不足以添加超过 2 个链接。但我认为这些链接提供了有趣的背景信息。所以我只是在“http(s):”后面省略了一个斜线。也许声誉更好的人可以修复链接并删除此注释。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用