Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#25397 closed Cleanup/optimization (fixed)

Warn of clash between generic view context variables and template context processor variables

Reported by: Mathieu Hinderyckx Owned by: Jacek Bzdak
Component: Documentation Version: 1.8
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

Problem

I have a custom User model, and a DetailView of that Model.

urls.py:

urlpatterns = [
    url(r'^(?P<pk>\d+)/$', views.UserDetailView.as_view(), name='user-detail'),
]

views.py:

class UserDetailView(DetailView):
    model = User
    template_name = 'app_example/profile.html'

Template:

<h2>Log in information</h2>
{% if user.is_authenticated %}
    <p>User authenticated. User oject: {{user}}.</p>
{% else %}
    <p>User not authenticated. User object: {{user}}.</p>
{% endif %}
 <h2>DetailView Object</h2>
<p>{{object}}</p>

To replicate the problem; Create 2 users, log in with 1 user, and visit the detailpage with the pk of the 2nd user. Do this also when both users are logged out.

Now, what happens is that the user.is_authenticated block is (wrongfully) always shown, and {{user}} is always the Detailview object instead of the request.user. The {{object}} is the Detailview object (as expected).

Problem

The documentation and example on DetailView mentions that its item is available through {{object}}. However, it's also available by default as {{obj._meta.model_name}} through the get_object_context_name() method from the SingleObjectMixin, which is not clearly mentioned. When using the 'User' model, this interferes with the {{user}} context variable from middleware. In any case (user = request.user or user = object), the 'is_authenticad' field on that variable should evaluate to False in the example above, but does not, why that is, is not clear to me yet. As this {{user}} variable is commonly used with authentication on sites, I think this should be mentioned clearly. Now, for example menu's for logged-in users only are shown while this shouldn't be. If this variable is the object from the DetailView instead of the request, this might lead to a lot of unexpected behaviour when developing templates.

Workaround

set 'context_object_name' on the DetailView to something else.

Change History (8)

comment:1 by Maxime Lorant, 9 years ago

Your solution seems to break forward compatibility, since the public method get_context_object_name describes the default behavior in the current documentation: https://docs.djangoproject.com/en/1.8/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.get_context_object_name, plus I think it is a good implementation, besides this case...

Maybe we could either :

  • exclude some reserved variable names (especially user and site). Problem: not really pretty and would be reserved to variables included by Django ;
  • change the behaviour if the variable is already used by one of the installed middleware. Problem: if you remove a middleware, it might break the generic view template (since the variable could be renamed as a side effect).

Both solutions have limits, especially the second one...

comment:2 by Tim Graham, 9 years ago

Component: Generic viewsDocumentation
Easy pickings: set
Summary: DetailView of User model breaks user context variable in templatesWarn of clash between generic view context varaibles and template context processor varaibles
Triage Stage: UnreviewedAccepted
Type: BugCleanup/optimization

I think trying to be "smart" and change or disallow the certain context variable names won't be worth it. I'd rather work to deprecate the auth context_processor (user can be replaced by request.user, but a solution for replacing perms isn't so clear). Meanwhile, we can certainly improve the documentation.

comment:3 by Maxime Lorant, 9 years ago

Summary: Warn of clash between generic view context varaibles and template context processor varaiblesWarn of clash between generic view context variables and template context processor variables

comment:4 by Jacek Bzdak, 9 years ago

Owner: changed from nobody to Jacek Bzdak
Status: newassigned

I'll do it

comment:5 by Tim Graham, 9 years ago

Has patch: set

comment:6 by Tim Graham <timograham@…>, 9 years ago

Resolution: fixed
Status: assignedclosed

In 494b7986:

Fixed #25397 -- Documented class-based view context variable clash with context processors.

comment:7 by Tim Graham <timograham@…>, 9 years ago

In d83454fb:

[1.8.x] Fixed #25397 -- Documented class-based view context variable clash with context processors.

Backport of 494b7986a3e5996d857b085f188a630d1504d9ca from master

comment:8 by Tim Graham <timograham@…>, 9 years ago

In 488538e:

[1.9.x] Fixed #25397 -- Documented class-based view context variable clash with context processors.

Backport of 494b7986a3e5996d857b085f188a630d1504d9ca from master

Note: See TracTickets for help on using tickets.
Back to Top