RequestContext is incorrectly delivered as request object when rendering a comment form/list in Django 1.10
adrysn opened this issue · 5 comments
In Django 1.10, some parameters were removed from render_to_string()
:
The dictionary and context_instance parameters for the following functions are removed:
- django.shortcuts.render()
- django.shortcuts.render_to_response()
- django.template.loader.render_to_string()
So, the prototype looks like below.
def render_to_string(template_name, context=None, request=None, using=None):
...
But, the render()
method in threadedcomments_tags.py
's RenderCommentFormNode
or RenderCommentListNode
class delivers context instance to the render_to_string()
as the third parameter, which should be a request object.
form_str = render_to_string(
template_search_list,
{"form" : self.get_form(context)},
context
)
Generally, it does not seem to cause errors, but sometimes it does. For my case, AttributeError: 'RequestContext' object has no attribute 'META'
occurred when used with Python Social Auth (I'll attach full traceback at the end for reference).
My problem was resolved by changing context
to context.get('request')
in render()
method or just removing context
from the method, but I'm not sure that is the correct fix.
Traceback
Traceback (most recent call last):
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/core/handlers/exception.py", line 39, in inner
response = get_response(request)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/core/handlers/base.py", line 217, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/core/handlers/base.py", line 215, in _get_response
response = response.render()
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/response.py", line 109, in render
self.content = self.rendered_content
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/response.py", line 86, in rendered_content
content = template.render(context, self._request)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/backends/django.py", line 66, in render
return self.template.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 208, in render
return self._render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/test/utils.py", line 94, in instrumented_test_render
return self.nodelist.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/loader_tags.py", line 174, in render
return compiled_parent._render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/test/utils.py", line 94, in instrumented_test_render
return self.nodelist.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/defaulttags.py", line 323, in render
return nodelist.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/loader_tags.py", line 70, in render
result = block.nodelist.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/defaulttags.py", line 323, in render
return nodelist.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/defaulttags.py", line 323, in render
return nodelist.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/threadedcomments/templatetags/threadedcomments_tags.py", line 204, in render
context
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/loader.py", line 68, in render_to_string
return template.render(context, request)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/backends/django.py", line 66, in render
return self.template.render(context)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/base.py", line 206, in render
with context.bind_template(self):
File "/Users/adrysn/.pyenv/versions/3.5.0/lib/python3.5/contextlib.py", line 59, in __enter__
return next(self.gen)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/debug_toolbar/panels/templates/panel.py", line 49, in _request_context_bind_template
context = processor(self.request)
File "/Users/adrysn/.pyenv/versions/neumann35/lib/python3.5/site-packages/django/template/context_processors.py", line 43, in debug
if settings.DEBUG and request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:
AttributeError: 'RequestContext' object has no attribute 'META'
Hi!
Can you post the changes to files to get work in django 1.10, please?
Hi, many thanks for the info, I've managed to get works with 1.10 with your suggestions
Just removing the third parameter context
from render_to_string
may raise following warning in Django>=1.10.
.../django/template/defaulttags.py:64: UserWarning: A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext.
This is because csrf_token
in context
object is not delivered to rendered comment form/list. So, original context
object should be given as the parameter of render_to_string
along with form
key.
I think render
method in RenderCommentFormNode
can be changed something like below.
context.push({"form": self.get_form(context)}
form_str = render_to_string(template_search_list, context)
context.pop()
Also, render
in RenderCommentListNode
may be changed to:
context.push({"comment_list": self.get_context_value_from_queryset(context, qs)})
liststr = render_to_string(template_search_list, context)
context.pop()
Dont remove the parameter, just change it to context.get('request')