Django自定义context_processors在render_to_string方法中

时间:2016-09-06 01:55:25

标签: python django

我正在构建一个发送电子邮件的函数,我需要在电子邮件的HTML模板中使用context_processor变量,但这不起作用。

示例:

def send_email(plain_body_template_name, html_body_template_name):
    plain_body = loader.render_to_string(plain_body_template_name, context)
    html_body = loader.render_to_string(html_body_template_name, context)
    email_msg = EmailMultiAlternatives(body=plain_body)
    email_msg.attach_alternative(html_body, 'text/html')
    email_message.send()

在我的自定义context_processor.py中,我只有一个接收HttpRequest的函数并返回类似{'foo': 'bar'}的字典,在模板中我尝试使用{{foo}}进行渲染。

我也在TEMPLATE['OPTIONS']['context_processors']添加了context_processor。

2 个答案:

答案 0 :(得分:9)

假设您使用django后面的TEMPLATE后端

'BACKEND': 'django.template.backends.django.DjangoTemplates',

django看到你没有传递请求并选择基本的Context来包装你的dict而不是RequestContext来处理你定义的context_processors

你可以放弃做

html_body = loader.render_to_string(html_body_template_name, context, request=request)

但您需要传入请求对象。

但这可能没有意义。您是否通过电子邮件发送了提出请求的人?包含上下文是否有意义?

如果您的上下文处理器不需要request,那么我要么使它成为一个简单的实用程序函数(如果它只在这里调用)或使请求参数可选,将其导入此模块,然后添加它直接进入上下文

context = {"my_var": 1} context.update(your_extra_context()) loader.render_to_string(...)

有一些复杂的方法来更新图层中的Context(),但我不认为这是必要的。

答案 1 :(得分:3)

我遇到了类似的问题 - 我需要使用上下文处理器值将模板渲染为字符串,但同时请求对象为None(从控制台运行命令)。然后我发现了这种方法:

from django.template.loader import render_to_string
from django.template import RequestContext
from django.shortcuts import render

def index(request):
    if not request:
        context = {'param1':'value1'}
        return render_to_string('myapp/index.html', RequestContext(None, context))
    else:
        #render as usual
        render(request, 'myapp/index.html', context)
        pass

当您传递RequestContext而不是字典时,它会将所有上下文处理器的值填充到上下文中。但是请求必须在所有上下文处理器中是可选的,否则这将不起作用。