Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RequestContext is incorrectly delivered as request object when rendering a comment form/list in Django 1.10 #78

Closed
adrysn opened this issue Aug 2, 2016 · 5 comments

Comments

@adrysn
Copy link

adrysn commented Aug 2, 2016

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 RenderCommentListNodeclass 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'
@KhanMaytok
Copy link

Hi!
Can you post the changes to files to get work in django 1.10, please?

@KhanMaytok
Copy link

Hi, many thanks for the info, I've managed to get works with 1.10 with your suggestions

@adrysn
Copy link
Author

adrysn commented Feb 15, 2017

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

@KhanMaytok
Copy link

Dont remove the parameter, just change it to context.get('request')

@vdboor
Copy link
Collaborator

vdboor commented Feb 19, 2017

I've fixed it slightly different in a243845
Using context.push() did have other errors when using context.flatten() as well.

I doubt there is a need to pass the request as the parent context is already enriched with the context_processors.

@vdboor vdboor closed this as completed Feb 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants