覆盖现有的Django模板标签

tom*_*tom 15 django django-templates

是否可以覆盖现有的Django模板标签,还是需要自定义模板文件并创建新的模板标签?

nca*_*vig 19

我正在寻找相同的答案,所以我想在这里分享我的解决方案.我想覆盖django中的默认url模板标记,而不必使用自定义模板标记并将其加载到每个模板文件中.

目标是用+(加号)替换%20(空格).这就是我想出来的......

init .py中

from django.template.defaulttags import URLNode

old_render = URLNode.render
def new_render(cls, context):
  """ Override existing url method to use pluses instead of spaces
  """
  return old_render(cls, context).replace("%20", "+")
URLNode.render = new_render
Run Code Online (Sandbox Code Playgroud)

这个页面很有用https://github.com/django/django/blob/master/django/template/defaulttags.py

  • @ncavig你好,您是在哪个“ init.py”中执行此操作的? (3认同)

nak*_*nis 9

我假设"现有的Django模板标签"是指不同应用中的标签.

创建一个templatetags/tagfile.py注册具有相同名称的标记.确保该tagfile名称与模板加载以{% load tagfile %}获取原始标记的名称相同.

此外,请确保您的应用程序列在原始应用程序之后INSTALLED_APPS.

  • 类似的想法:您可以从其他库加载“register”对象(另一个库应该具有类似“register = template.Library()”的内容,然后它通过执行“@register.tag”等来注册标签。可以导入 `register` 而不是实例化您自己的,并执行 `@register.tag(tag_name='existing_tag')` (2认同)

小智 5

我很确定您要求完全覆盖 django templatetag

简短的答案是 -Yes您可以覆盖现有的templatetag.

以下是如何实现它:

  • 您必须将模板目录包含在settings
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'your_app/templates')],
            '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',
                    'django.template.context_processors.static',
                ],
            },
        },
    ]
Run Code Online (Sandbox Code Playgroud)
  • 您必须将要覆盖的应用程序包含templatetagINSTALLED_APPS
INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'your_app_name',
        ...
    ]
Run Code Online (Sandbox Code Playgroud)

重要的是让你的应用程序位于 django 的应用程序之后!

这是由于 django 的工作方式造成的。我们将充分利用这一点。

  • 现在,在您的应用程序中创建一个名为templatetags. __init__.py在 中包含文件很重要templatetags,这样 django 才能理解它是一个 python 包!:

your_app_name/templatetags/__init__.py

  • 创建templatetag您想要覆盖的。在该示例中,我将使用该admin_list.py标签。

在这种情况下,它应该这样放置:

your_app_name/templatetags/admin_list.py

  • admin_list.py 现在复制(非常重要!)的全部内容django.contrib.admin.templatetags.admin_list.py并修改您想要的任何内容。

重要的是要有 django 管理的全部内容admin_list.py,而不仅仅是一段代码,否则它将无法工作!


工作原理:Django 在您的应用程序中查找templatetags文件夹并使用其中的模板标签。它将您的模板标签放置在模板标签之后,admin's简而言之 - 它会覆盖它们,因为它们放置django.adminINSTALLED_APPS.

不要忘记:

  • ./manage.py collectstatic
  • DEBUG = False

在生产中。

我已经测试了它的result_list(cl)功能覆盖,并且它正在工作。


该解决方案无需自定义 html 模板文件即可工作。

希望有帮助。


Wil*_*ams 2

是的。

由于 django 基本上是一个 python 库(与 python 中的所有内容一样),您可以覆盖您想要的任何内容。

目前尚不清楚您到底想做什么,但滚动您自己的模板标签确实非常容易,文档非常清楚: https: //docs.djangoproject.com/en/dev/howto/custom-template -标签/#writing-custom-template-tags

这是疯狂的基础,但这是我用来开始构建自定义模板标签的模板:

myapp/templatetags/my_custom_tags.py (必须__init__.py在此目录中)

from django import template
register = template.Library()

class CustomTag(template.Node):
    def render(self, context):
        context['my_custom_tag_context'] = "this is my custom tag, yeah"
        return ''

@register.tag(name='get_custom_tag')
def get_custom_tag(parser, token):
    return CustomTag()
Run Code Online (Sandbox Code Playgroud)

模板中的用法如下:

{% load my_custom_tags %}
{% get_custom_tag %}
{{my_custom_tag_context}}
Run Code Online (Sandbox Code Playgroud)

您可能想要解析,并且您可能想要在类中token进行某种操作,但它确实显示了它的基础程度。__init__


您可以浏览现有的“默认”模板标签,根据您的喜好复制和修改它们。

那里确实有一些很棒的东西: https ://github.com/django/django/blob/master/django/template/defaulttags.py

  • 好吧,这个例子展示了如何创建一个新标签,但是如何在单独的 py 文件中覆盖这个现有标签呢?不必要时我不想碰模板文件。 (10认同)