Opened 8 years ago

Closed 7 years ago

Last modified 7 years ago

#28131 closed Bug (fixed)

Template variable "perms" single-attribute lookup does not work as documented

Reported by: Meiyer Owned by: Botond Béres
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: no UI/UX: no

Description

The documentation states that the template variable perms may be used with single-attribute lookup {{ perms.foo }} to check for module-level permissions, proxying to User.has_module_perms.
This is not the case in reality. Using single-attribute lookup causes the tag to output all permissions the user has in the module foo, as text.

This is caused by django.contrib.auth.context_processors.PermWrapper’s method

    def __getitem__(self, app_label):
        return PermLookupDict(self.user, app_label)

which in turn invokes the PermLookupDict’s method

    def __repr__(self):
        return str(self.user.get_all_permissions())

The behaviour is different from the {{ "foo" in perms }} construct, which resolves to PermWrapper’s __contains__ that correctly casts the operation to a boolean, causing the PermLookupDict’s method

    def __bool__(self):
        return self.user.has_module_perms(self.app_label) 

to be used instead.

This issue goes back to at least version 1.6 and forward through all versions up to 1.11 (and apparently the single-attribute lookup feature is not used by anyone because this issue went unreported for at least four years).

Change History (7)

comment:1 by Tim Graham, 8 years ago

Component: Template systemDocumentation
Summary: Template variable "perms" single-attribute lookup does not work as expectedTemplate variable "perms" single-attribute lookup does not work as documented
Triage Stage: UnreviewedAccepted

I confirmed the same behavior as far back as Django 1.4. From a quick glance, I don't see a way to change the code to conform to the documentation, so I think it's best to correct the docs based on the current behavior.

comment:2 by Simon Charette, 8 years ago

Tim, I think the confusion here is that {{ perms.foo }} should be checked against with a conditional statement (e.g. {% if perms.foo %}) to work.

The behavior reported here is expected, trying to use {{ boolean_var }} won't perform any check by itself and result in bool.__repr__ just like {{ perms.foo }} results in PermLookupDict.__repr__.

I think the documentation is just a bit misleading and should be using {% if perms.foo %} to exemplify its usage.

comment:3 by brian houston morrow, 8 years ago

Owner: changed from nobody to brian houston morrow
Status: newassigned

comment:4 by Botond Béres, 7 years ago

Owner: changed from brian houston morrow to Botond Béres

comment:5 by Botond Béres, 7 years ago

Has patch: set

Added a PR where I've tried to replace and rephrase the incorrect/misleading examples.

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

Resolution: fixed
Status: assignedclosed

In 51d7feff:

Fixed #28131 -- Corrected examples of using attribute lookups on the "perms" template variable.

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

In 41009788:

[2.0.x] Fixed #28131 -- Corrected examples of using attribute lookups on the "perms" template variable.

Backport of 51d7feff872e74d5a53479f62163d5e0024b00ed from master

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