Jinja2报错AttributeError: 'Environment'对象无get_source属性
问题原因分析
错误AttributeError: 'Environment' object has no attribute 'get_source'的核心原因是第二行模板使用了{% include %}标签,而当前环境的BaseLoader无法处理外部模板加载:
- 第一行的
template.email_subject仅做简单变量替换,未引用外部模板,用BaseLoader配合from_string生成的模板可正常渲染,无需加载额外文件。 - 第二行的
template.email_template包含{% include invoiceType+'/email_body.tpl' %},Jinja2处理该标签时,会调用环境加载器的get_source方法读取指定路径的模板文件,但BaseLoader是抽象基类,未实现get_source核心方法,因此触发属性不存在的错误。
解决办法
根据模板文件的存储方式,选择以下方案之一:
1. 使用文件系统加载器(FileSystemLoader)
如果invoiceType/email_body.tpl存放在本地文件系统的某个目录下,直接用FileSystemLoader替换BaseLoader并指定模板根目录:
from jinja2 import Environment, FileSystemLoader # 假设模板文件在当前目录,可替换为实际路径如"./templates" env = Environment(loader=FileSystemLoader('.')) body = env.from_string(template.email_template).render(bodyContext)
2. 自定义加载器实现get_source方法
若模板存储在数据库或内存中,可继承BaseLoader并实现get_source方法,告知Jinja2如何获取指定名称的模板内容:
from jinja2 import Environment, BaseLoader, TemplateNotFound class CustomLoader(BaseLoader): def get_source(self, environment, template): # 示例:模板内容存储在字典中,可根据实际存储方式修改逻辑 templates = { "invoiceType/email_body.tpl": "im Anhang findest du/findet ihr den Entwurf für die kommende Rechnung über alle angefallenen Kosten bis zum {{invoiceDate -}}." } if template not in templates: raise TemplateNotFound(template) return templates[template], template, lambda: False env = Environment(loader=CustomLoader()) body = env.from_string(template.email_template).render(bodyContext)
3. 移除include标签,直接内嵌内容
若模板内容简单,可将email_body.tpl的内容直接写入template.email_template,避免外部模板加载:
# 修改后的template.email_template内容 """ Hallo {{name}}, im Anhang findest du/findet ihr den Entwurf für die kommende Rechnung über alle angefallenen Kosten bis zum {{invoiceDate -}}. Viele Grüße {{emailFooter}} """
内容的提问来源于stack exchange,提问作者Tanne
相关产品推荐
相关产品推荐

