python_django_customTemplate 悠悠 2022-01-14 23:01 125阅读 0赞 # Custom template tags and filters # Django’s template language comes with a wide variety of [built-in tags and filters][] designed to address the presentation logic needs of your application. Nevertheless, you may find yourself needing functionality that is not covered by the core set of template primitives. You can extend the template engine by defining custom tags and filters using Python, and then make them available to your templates using the [`{%load %}`][load] tag. Django的模板语言带有各种内置标记和过滤器,旨在满足应用程序的表示逻辑需求。然而,您可能会发现自己需要的功能并没有被核心模板原语集所覆盖。您可以通过使用python定义自定义标记和过滤器来扩展模板引擎,然后使用%load%标记将它们提供给模板。 Code layout Django的模板语言带有各种内置标记和过滤器,旨在满足应用程序的表示逻辑需求。然而,您可能会发现自己需要的功能并没有被核心模板原语集所覆盖。您可以通过使用python定义自定义标记和过滤器来扩展模板引擎,然后使用%load%标记将它们提供给模板。 ***Development server won’t automatically restart*** *After adding the `templatetags` module, you will need to restart your server before you can use the tags or filters in templates.* 您的自定义标记和过滤器将位于templateTags目录内的模块中。模块文件的名称是稍后加载标记时使用的名称,因此请小心选择一个不会与其他应用程序中的自定义标记和筛选器冲突的名称。 例如,如果自定义标记/过滤器位于名为poll\_extras.py的文件中,则应用程序布局可能如下所示: polls/ __init__.py models.py templatetags/ __init__.py poll_extras.py views.py And in your template you would use the following: {% load poll_extras %} 包含自定义标记的应用程序必须位于已安装的应用程序中,以便 [`{% load %}`][load] 来使用,这是一个安全特性:它允许您在一台主机上为许多模板库托管python代码,而不允许在每次Django安装时访问所有模板库。 在templateTags包中放入的模块数量没有限制。 \{% load %\}语句将为给定的python模块名加载标记/过滤器,而不是应用程序名。 要成为有效的标记库,模块必须包含一个名为register的模块级变量,该变量是一个template.library实例,其中注册了所有标记和筛选器。因此,在模块顶部附近,放置以下内容: from django import template register = template.Library() New in Django 1.9. 模板标记模块可以通过“libraries”参数注册到djangotemplates。如果要在加载模板标记时使用与模板标记模块名称不同的标签,则此选项非常有用。它还允许您在不安装应用程序的情况下注册标记。 -------------------- ## Writing custom template filters ## 自定义过滤器只是采用一个或两个参数的python函数: * 变量(输入)的值-不一定是字符串。 * 参数的值——可以有一个默认值,也可以完全忽略。 例如,在过滤器`{ { var|foo:"bar" }}`, 中,过滤器foo将传递变量var和参数“bar”。 由于模板语言不提供异常处理,因此从模板筛选器引发的任何异常都将暴露为服务器错误。因此,如果要返回合理的回退值,则筛选函数应避免引发异常。如果输入在模板中表示一个明显的错误,那么引发异常可能仍然比隐藏错误的静默失败要好。 下面有一个案例 def cut(value, arg): """Removes all values of arg from the given string""" return value.replace(arg, '') 下面是如何使用该过滤器的示例: { { somevariable|cut:"0" }} 大多数过滤器不接受参数。在这种情况下,只需将参数从函数中去掉。例子: def lower(value): # Only one argument. """Converts a string into all lowercase""" return value.lower() ### Registering custom filters ### `django.template.Library.``filter`() 编写完过滤器定义后,需要将其注册到库实例中,以使其可用于Django的模板语言: register.filter('cut', cut) register.filter('lower', lower) The `Library.filter()` method takes two arguments: 1. The name of the filter – a string. 2. The compilation function – a Python function (not the name of the function as a string). You can use `register.filter()` as a decorator instead: @register.filter(name='cut') def cut(value, arg): return value.replace(arg, '') @register.filter def lower(value): return value.lower() 如果不使用name参数,如上面的第二个示例中所示,Django将使用函数的名称作为过滤器名称。 最后,register.filter()还接受三个关键字参数,是安全的,需要自动转义,并期望本地时间。这些参数在下面的过滤器和自动转义以及过滤器和时区中描述。 -------------------- ### Template filters that expect strings ### `django.template.defaultfilters.``stringfilter`() If you’re writing a template filter that only expects a string as the first argument, you should use the decorator stringfilter. This will convert an object to its string value before being passed to your function from django import template from django.template.defaultfilters import stringfilter register = template.Library() @register.filter @stringfilter def lower(value): return value.lower() 这样,您就可以将一个整数传递给这个过滤器,并且不会导致attributeError(因为整数没有lower()方法)。 ### Filters and time zones ### 如果您编写一个对日期时间对象进行操作的自定义过滤器,那么您通常会将其注册为expected\\localtime标志设置为true。 @register.filter(expects_localtime=True) def businesshours(value): try: return 9 <= value.hour < 17 except AttributeError: return '' 设置此标志后,如果筛选器的第一个参数是时区感知日期时间,Django将根据模板中时区转换规则,在将其传递给筛选器之前将其转换为当前时区。 -------------------- ## Writing custom template tags ## 标签比过滤器更复杂,因为标签可以做任何事情。Django提供了许多快捷方式,使大多数类型的标记更容易编写。首先,我们将研究这些快捷方式,然后解释如何在快捷方式不够强大时从头开始为这些情况编写标记。 ### Simple tags ### `django.template.Library.``simple_tag`() 许多模板标记接受许多参数(字符串或模板变量),并在仅基于输入参数和一些外部信息进行一些处理后返回结果。例如,当前的时间标记可能接受格式字符串,并将时间作为相应格式的字符串返回。 为了简化这些类型标记的创建,Django提供了一个助手函数,即简单的标记。此函数是django.template.library的一种方法,它接受一个接受任意数量参数的函数,将其包装在一个呈现函数和上面提到的其他必要位中,并将其注册到模板系统中。 因此,我们当前的时间函数可以这样写: import datetime from django import template register = template.Library() @register.simple_tag def current_time(format_string): return datetime.datetime.now().strftime(format_string) A few things to note about the `simple_tag` helper function * Checking for the required number of arguments, etc., has already been done by the time our function is called, so we don’t need to do that. * The quotes around the argument (if any) have already been stripped away, so we just receive a plain string. * If the argument was a template variable, our function is passed the current value of the variable, not the variable itself If your template tag needs to access the current context, you can use the `takes_context` argument when registering your tag @register.simple_tag(takes_context=True) def current_time(context, format_string): timezone = context['timezone'] return your_get_current_time_method(timezone, format_string) 注意,第一个参数必须称为上下文。 有关takes-context选项如何工作的详细信息,请参阅包含标记部分。 如果需要重命名标记,可以为其提供自定义名称。 register.simple_tag(lambda x: x - 1, name='minusone') @register.simple_tag(name='minustwo') def some_function(value): return value - 2 `simple_tag` functions 可以接受任意数量的位置或关键字参数。例如: @register.simple_tag def my_tag(a, b, *args, **kwargs): warning = kwargs['warning'] profile = kwargs['profile'] ... return ... 然后在模板中,任何数量的参数(用空格分隔)都可以传递给模板标记。与Python一样,关键字参数的值是使用等号(“=”)设置的,并且必须在位置参数之后提供。例如 {% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %} 可以将标记结果存储在模板变量中,而不是直接输出它。这是通过使用as参数和变量名来完成的。这样做可以让您自己输出您认为合适的内容: {% get_current_time "%Y-%m-%d %I:%M %p" as the_time %} <p>The time is { { the_time }}.</p> 简单实现 [https://blog.csdn.net/qq\_25046261/article/details/79577933][https_blog.csdn.net_qq_25046261_article_details_79577933] [built-in tags and filters]: https://docs.djangoproject.com/es/1.9/ref/templates/builtins/ [load]: https://docs.djangoproject.com/es/1.9/ref/templates/builtins/#std:templatetag-load [https_blog.csdn.net_qq_25046261_article_details_79577933]: https://blog.csdn.net/qq_25046261/article/details/79577933
还没有评论,来说两句吧...