要创建自定义django
模板标签和过滤器,以及添加自定义manage.py
命令(无论多么琐碎),文档都会告诉您创建特定的目录结构。
我正在做一个非常小的项目,只是为了添加一个小过滤器或命令而将应用程序的结构复杂性加倍让我很痛苦。
有什么方法可以以紧凑、直接的方式注册标签、过滤器和命令?必须在我想要的任何地方,而不是在目录层次结构中声明性地降低 2 级?
要创建自定义django
模板标签和过滤器,以及添加自定义manage.py
命令(无论多么琐碎),文档都会告诉您创建特定的目录结构。
我正在做一个非常小的项目,只是为了添加一个小过滤器或命令而将应用程序的结构复杂性加倍让我很痛苦。
有什么方法可以以紧凑、直接的方式注册标签、过滤器和命令?必须在我想要的任何地方,而不是在目录层次结构中声明性地降低 2 级?
虽然有点骇人听闻,但事实证明它完全可以用于标签/过滤器案例。命令,不:django 实际上在文件系统中搜索所.py
涉及的文件。
模板破解是完全独立的——它不会将可疑的东西泄漏到附近的代码中。单个模块可以容纳所有超魔,并由常规模块导入。
首先,我们必须创建一个模拟模块。我们将创建一个漂亮的装饰器来将常规类转换为模块:
def module(path):
def decorator(cls):
if '.' in path:
parent_path, name = path.rsplit('.', 1)
module(parent_path)(type(name, (object,), { name: cls }))
return sys.modules.setdefault(path, cls)
return decorator
是的,递归是必要的(我们需要模拟完整的导入路径),它可以用来创建一个templatetags
像这样的假模块:
@module('app.templatetags.extras')
class TemplateExtras(object):
class register:
tags = {}
filters = {}
# Optional: avoid using {% load %}:
django.template.libraries['app.templatetags.extras'] = TemplateExtras
django.template.base.add_to_builtins('app.templatetags.extras')
再添加两个漂亮的装饰器...
def templatetag(f):
return TemplateExtras.register.tags.setdefault(f.__name__, f)
def templatefilter(f):
return TemplateExtras.register.filters.setdefault(f.__name__, f)
...您会得到以下简洁明了的语法:
# imported or present in app/__init__.py
@templatefilter
def datestr(date):
return datetime.strftime(date, '%Y-%m-%d')