你如何在Jinja2模板中使用Django模板标签?

4
有许多现成的Django包提供模板标签,尽管我的项目使用Jinja2,我仍然想在其中使用这些标签。
我看到了一些解决方案,允许其他模板引擎使用Django标签。它们涉及在字符串中创建一个小模板,并将其与当前上下文一起传递给Django模板处理器。以下是两个示例:Mako模板使用Django模板标签Jinja2模板使用Django模板标签
我想知道是否有更少hackish的解决方案。
2个回答

1

很遗憾,Django模板标签不能直接转换为Jinja。

Django模板标签可以做许多不同的事情,并且通常实现为函数。幸运的是,Jinja可以将这些函数注册为全局变量并调用它们。这适用于“简单”的模板标签。

如果您正在使用官方的Django Jinja2后端,请参见https://docs.djangoproject.com/en/4.1/topics/templates/#django.template.backends.jinja2.Jinja2以了解如何将函数(在此情况下为您的模板标签)注册为全局变量。完成此操作后,您可以在模板中调用该函数,例如{{ your_tag_function() }}。记得传递模板标签函数需要的任何参数!

我喜欢使用https://github.com/niwinz/django-jinja后端,如果您也在使用这个后端,请参考https://niwi.nz/django-jinja/latest/#_custom_filters_globals_constants_and_tests来了解如何将函数注册为全局函数。

不幸的是,这仅适用于“简单”的标签。有些标签是“包含标签”或者依赖于Django模板引擎。由于Django模板无法在Jinja引擎中呈现,因此您需要做更多的工作来翻译这些类型的标签。您需要查看源代码以区分它们并了解它们的功能。

对于更复杂的标签,我通常会在我的Django应用程序中创建一个“jinja_functions.py”脚本,然后在该脚本中导入原始模板标签。然后我编写一个函数来包装它-调用原始函数,通常得到一个字典,然后使用该字典来渲染一个字符串,该字符串被返回...大多数标签都足够简单,我只需使用f字符串或.format将它们与字典结果格式化。

接下来,我将我的新封装函数注册为Jinja全局变量,并在Jinja模板中使用它!

以下是一个示例,其中我重新实现了https://github.com/timonweb/django-tailwind提供的模板标签,以便与Jinja一起使用。我将tailwind_css和tailwinf_preload_css标签合并到一个函数中,即tailwind_css函数,并按照上面的说明将其作为全局变量注册到Jinja中,然后我可以在我的模板中调用该函数,如{{ tailwind_css(prefetch=True) }}或者{{ tailwind_css() }}

from django.templatetags.static import static
from tailwind import get_config
from tailwind.utils import is_path_absolute

def tailwind_css(v=None, prefetch=False):

    tailwind_css_path = get_config("TAILWIND_CSS_PATH")
    if not is_path_absolute(tailwind_css_path):
        tailwind_css_path = static(tailwind_css_path)
    if v:
        tailwind_css_path = f"{tailwind_css_path}?v={v}"
    if prefetch:
        rel = 'rel="preload"'
        as_str = ' as="style"'
    else:
        rel = 'rel="stylesheet"'
        as_str = ""

    return f'<link {rel} href="{tailwind_css_path}"{as_str}>'

总之,对于“简单”的标签,它可以直接在Jinja中注册为全局函数,因此它可以很好地开箱即用...但是对于“include”标签或其他依赖于Django模板引擎的标签,您将不得不编写自己的函数:( 但通常这并不需要太多的工作!

0
移动问题到Python的范围内,然后将一个Python函数导入到另一个函数中,可以这样实现:
在你的your_jinja_templatetags.py文件中:
from some_django_templatetags import somefilter as base_somefilter

@library.filter
def somefilter(value):
   return base_somefilter(value)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接