要创建自定义django
模板标记和过滤器,以及添加自定义manage.py
命令,无论多么微不足道,文档都会告诉您创建特定的目录结构。
我正在开展一个非常小的项目,我很难将应用程序的结构复杂性加倍,只是为了添加一个小小的过滤器或命令。
有没有办法以紧凑,直接的方式注册标签,过滤器和命令?在我想要的任何地方势不可挡,而不是在目录层次结构中以声明的方式2级?
答案 0 :(得分:0)
虽然有点hackish,但事实证明标签/过滤器的情况完全可能。命令,否:django实际上在文件系统中搜索所涉及的.py
文件。
模板hack是完全独立的 - 它不会将可疑的东西泄漏到附近的代码中。单个模块可以容纳所有的metamagic,并由常规模块导入。
首先,我们必须创建一个模拟模块。我们将创建一个很好的装饰器来将常规类转换为模块:
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')