Opened 2 years ago

Closed 23 months ago

Last modified 23 months 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 Changed 2 years ago by Tim Graham

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 Changed 2 years ago by Simon Charette

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 Changed 2 years ago by brian houston morrow

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

comment:4 Changed 23 months ago by Botond Béres

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

comment:5 Changed 23 months ago by Botond Béres

Has patch: set

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

comment:6 Changed 23 months ago by Tim Graham <timograham@…>

Resolution: fixed
Status: assignedclosed

In 51d7feff:

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

comment:7 Changed 23 months ago by Tim Graham <timograham@…>

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