Rodolpho Pivetta Rodolpho Pivetta - 24 days ago 17
Python Question

Django custom context_processors in render_to_string method

I'm building a function to send email and I need to use a context_processor variable inside the HTML template of the email, but this don't work.

Example:

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()


In my custom
context_processor.py
I just have a function that receive a
HttpRequest
and return a dict like
{'foo': 'bar'}
, and in the template I try to render using
{{foo}}
.

I added the context_processor in the
TEMPLATE['OPTIONS']['context_processors']
too.

Answer

Assuming you're using the django backend in your TEMPLATE with

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

django is seeing that you haven't passed in a request and opting for a basic Context to wrap your dict instead of a RequestContext which will handle the context_processors you've defined.

You can probably get away with doing

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

but you'd need to pass in the request object.

This might not make sense though. Are you emailing the person making the request? Does the context make sense to include?

If your context processor doesn't need the request then I'd either make it a simple utility function (if it's only called here) or make the request parameter optional, import it into this module, and add it directly into the context

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

There are some complicated ways of updating a Context() in layers, but I don't think that's necessary here.

Comments