17

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

4

5 回答 5

21

我一直在寻找相同的答案,所以想在这里分享我的解决方案。我想覆盖 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

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

于 2013-11-15T20:15:32.167 回答
10

我假设“现有的 Django 模板标签”是指不同应用程序中的标签。

创建一个templatetags/tagfile.py注册同名标签的。确保它tagfile与模板加载{% load tagfile %}用于获取原始标签的名称相同。

此外,请确保您的应用列在INSTALLED_APPS.

于 2013-10-08T14:54:19.777 回答
2

是的。

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

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

您的模板中的用法如下所示:

{% load my_custom_tags %}
{% get_custom_tag %}
{{my_custom_tag_context}}

您可能想要解析token,并且您可能想要在课堂上使用某种东西__init__,但它确实表明它是多么基本。


您可以浏览现有的“默认”模板标签,将它们复制并修改为您喜欢的内容。

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

于 2012-11-05T09:43:31.457 回答
2

我很确定您要求完全覆盖 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',
                ],
            },
        },
    ]
  • 您必须在以下内容中包含要覆盖的应用templatetag程序 INSTALLED_APPS
INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'your_app_name',
        ...
    ]

重要的是在 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.admin放在INSTALLED_APPS.

不要忘记:

  • ./manage.py collectstatic
  • DEBUG = False

在生产中。

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


此解决方案在没有自定义 html 模板文件的情况下有效。

希望有帮助。

于 2019-04-09T16:25:29.240 回答
1

如果您不想依赖 settings.py 中应用程序的顺序INSTALLED_APPS,则可以尝试以下操作:

像往常一样创建模板标签函数/类。假设您要覆盖otherapp_tags.current_time从名为other_app. 首先,创建您自己的该函数/类的版本:

def my_current_time(format_string):
    return datetime.datetime.now().strftime(format_string)

然后,不要在您的应用程序命名空间中注册此函数/类,而是从另一个应用程序修补现有函数:

from other_app.templatetags import otherapp_tags

otherapp_tags.register.tags['current_time'] = my_current_time

通常,您应该在AppConfig'sready()方法中执行此操作。

于 2019-01-25T15:39:49.213 回答