Django自定义上下文处理器在邮件模板中无法生效的问题
问题原因
Django的上下文处理器仅在通过视图的模板响应(如TemplateResponse、render函数)渲染页面模板时自动生效。而你手动使用template.render(context)渲染邮件模板时,只会使用你传入的context字典,不会自动加载配置的上下文处理器,因此cname变量无法被注入到邮件模板中。
解决方案
方案1:手动调用上下文处理器并合并到context
修改utils.py中的邮件发送函数,传入request参数并手动调用上下文处理器,将其返回的数据合并到邮件模板的上下文里:
# utils.py from yourapp.context_processors import cname # 替换为你的上下文处理器实际路径 def account_creation_email(to, full_name, url, request): # 新增request参数 template = get_template('mail/account-creation.html') # 调用上下文处理器获取cname数据 processor_data = cname(request) # 合并原有上下文与处理器数据 context = { "full_name": full_name, "url": url, **processor_data # 展开合并字典 } html = template.render(context) email = EmailMultiAlternatives( subject="Account Creation Email", body=html, to=[to] ) email.attach_alternative(html, "text/html") email.send()
同时修改视图中的调用,传入request对象:
# 视图代码中更新调用 account_creation_email(account.email, f"{account.full_name}", url=url, request=self.request)
方案2:使用render_to_string自动加载上下文处理器
Django的render_to_string函数支持传入request参数,会自动加载配置的所有上下文处理器,无需手动调用:
# utils.py from django.template.loader import render_to_string def account_creation_email(to, full_name, url, request): # 传入request后自动加载上下文处理器 html = render_to_string( 'mail/account-creation.html', {"full_name": full_name, "url": url}, request=request ) email = EmailMultiAlternatives( subject="Account Creation Email", body=html, to=[to] ) email.attach_alternative(html, "text/html") email.send()
视图中同样需要传入request=self.request。
方案3:直接从租户获取公司名称(更高效)
如果仅需要公司名称,可直接从当前租户对象中提取,无需依赖上下文处理器:
# 视图代码中获取公司名称 def form_valid(self, form): # ... 原有代码 ... # 直接从当前租户获取公司名称 company_name = self.request.tenant.company_name # 传入邮件函数 account_creation_email(account.email, f"{account.full_name}", url=url, company_name=company_name) return super().form_valid(form) # utils.py修改 def account_creation_email(to, full_name, url, company_name): template = get_template('mail/account-creation.html') context = { "full_name": full_name, "url": url, "company_name": company_name } html = template.render(context) # ... 邮件发送代码 ...
邮件模板中对应修改为:
<div>An admin at the company intranet for {{ company_name }} just added an account for you to the site.</div>
内容的提问来源于stack exchange,提问作者Finn
相关产品推荐
相关产品推荐

