[Django]-Django 1.11 TypeError context must be a dict rather than Context

72👍

In Django 1.8+, the template’s render method takes a dictionary for the context parameter. Support for passing a Context instance is deprecated, and gives an error in Django 1.10+.

In your case, just use a regular dict instead of a Context instance:

message = get_template('email_forms/direct_donation_form_email.html').render(ctx)

You may prefer to use the render_to_string shortcut:

from django.template.loader import render_to_string

message = render_to_string('email_forms/direct_donation_form_email.html', ctx)

If you were using RequestContext instead of Context, then you would pass the request to these methods as well so that the context processors run.

message = get_template('email_forms/direct_donation_form_email.html').render(ctx, request=request)
message = render_to_string('email_forms/direct_donation_form_email.html', ctx, request=request)

19👍

Migrated from Django 1.8 to Django 1.11.6

Wherever i had a RequestContext class, there is a method flatten() wich return the result as a dict.

So if the class is RequestContext….

return t.render(context)

becomes

return t.render(context.flatten())

And in a case wich the context is is wrapped by Context(), just remove it. Because Context() is deprecated.

return t.render(Context(ctx))

becomes

return t.render(ctx)

2👍

For django 1.11 and after, context must be dict.

You can use:

context_dict = get_context_dict(context)
return t.render(context_dict)

or

context_dict = context.flatten()
return t.render(context_dict)

0👍

I got here because I had the same issue. I’m learning Django with Django Unleashed by Andrew Pinkham. It’s a book from 2015.

I found in the official documentation, that a dictionary must be passed to the context parameter and not a Context instance (from django.template.Context).

@Alasdair suggested to use render_to_string, but, at least in Django 3.2 the
render method use render_to_string method intrinsically.

def render(request, template_name, context=None, content_type=None, status=None, using=None):
"""
Return a HttpResponse whose content is filled with the result of calling
django.template.loader.render_to_string() with the passed arguments.
"""
content = loader.render_to_string(template_name, context, request, using=using)
return HttpResponse(content, content_type, status)

so, using just the render method could be better. I provide this answer because was the one that I was looking for and it may help some one reaching this Stack Overflow question.

Leave a comment