Code

Opened 5 years ago

Closed 5 years ago

#12037 closed (fixed)

A ContextLazyObject-wrapped User breaks {% url myurlname user %}

Reported by: chipx86 Owned by: lukeplant
Component: contrib.auth Version: 1.1
Severity: Keywords:
Cc: chipx86@… Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

r11623 breaks the {% url %} tag with 'user' (provided by the auth context processor) as an argument. Instead of 'user' being seen as a User object and transformed into a string, it's seen as a ContextLazyObject, which fails.

Now, maybe it's okay and that call sites should be expected to make sure they're passing the specific string instead of an object being represented as a string through __unicode__, but it does break some existing code. It should be explicit in the documentation if the decision is to not allow this anymore. I will point out though that it continues to work with other objects. I suspect what's really needed is that ContextLazyObject or LazyObject should be fixed so that it can be passed as a parameter in {% url %}.

The following template code (assuming a named url of "userpage") reproduces this for our app:

{% url userpage user %}

And this will show the following exception:

NoReverseMatch: Reverse for 'userpage' with arguments '(<django.core.context_processors.ContextLazyObject object at 0x124e190>,)' and keyword arguments '{}' not found.
Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/django/core/handlers/base.py", line 92, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/home/chipx86/src/rb/reviewboard/reviewboard/accounts/decorators.py", line 27, in _check
    return view_func(*args, **kwargs)
  File "/home/chipx86/src/rb/reviewboard/reviewboard/reviews/views.py", line 246, in review_detail
    'PRE_CREATION': PRE_CREATION,
  File "/usr/local/lib/python2.6/dist-packages/django/shortcuts/__init__.py", line 20, in render_to_response
    return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
  File "/usr/local/lib/python2.6/dist-packages/django/template/loader.py", line 108, in render_to_string
    return t.render(context_instance)
  File "/usr/local/lib/python2.6/dist-packages/django/template/__init__.py", line 178, in render
    return self.nodelist.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/__init__.py", line 779, in render
    bits.append(self.render_node(node, context))
  File "/usr/local/lib/python2.6/dist-packages/django/template/debug.py", line 71, in render_node
    result = node.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/loader_tags.py", line 97, in render
    return compiled_parent.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/__init__.py", line 178, in render
    return self.nodelist.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/__init__.py", line 779, in render
    bits.append(self.render_node(node, context))
  File "/usr/local/lib/python2.6/dist-packages/django/template/debug.py", line 71, in render_node
    result = node.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/loader_tags.py", line 97, in render
    return compiled_parent.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/__init__.py", line 178, in render
    return self.nodelist.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/__init__.py", line 779, in render
    bits.append(self.render_node(node, context))
  File "/usr/local/lib/python2.6/dist-packages/django/template/debug.py", line 71, in render_node
    result = node.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/loader_tags.py", line 24, in render
    result = self.nodelist.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/__init__.py", line 779, in render
    bits.append(self.render_node(node, context))
  File "/usr/local/lib/python2.6/dist-packages/django/template/debug.py", line 71, in render_node
    result = node.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/loader_tags.py", line 111, in render
    return self.template.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/__init__.py", line 178, in render
    return self.nodelist.render(context)
  File "/usr/local/lib/python2.6/dist-packages/django/template/__init__.py", line 779, in render
    bits.append(self.render_node(node, context))
  File "/usr/local/lib/python2.6/dist-packages/django/template/debug.py", line 81, in render_node
    raise wrapped
TemplateSyntaxError: Caught an exception while rendering: Reverse for 'userpage' with arguments '(<django.core.context_processors.ContextLazyObject object at 0x124e190>,)' and keyword arguments '{}' not found.

Attachments (0)

Change History (3)

comment:1 Changed 5 years ago by lukeplant

  • Needs documentation unset
  • Needs tests unset
  • Owner changed from nobody to lukeplant
  • Patch needs improvement unset

I think this is caused by the fact that LazyObject does not proxy the str method. I'll try to fix ASAP.

comment:2 Changed 5 years ago by lukeplant

I cannot reproduce - I've tried with Python 2.4, 2.5, 2.6. In r11625 I've committed a change that fixes a bug on Python 2.6, and introduced a test for this bug (which was also failing on Python 2.6, but not with a NoReverseMatch).

Could you try the latest trunk and see if you still have the problem? If so, please run ./tests/runtests.py context_processors and post the result, along with what version of Python you are using etc.

comment:3 Changed 5 years ago by chipx86

  • Resolution set to fixed
  • Status changed from new to closed

Thanks, our builds are no longer tripping up on this :) Not sure why you weren't able to reproduce it. Maybe there was something more subtle going on, but this fixes it regardless.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.