#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 , 9 years ago
| Component: | Template system → Documentation |
|---|---|
| Summary: | Template variable "perms" single-attribute lookup does not work as expected → Template variable "perms" single-attribute lookup does not work as documented |
| Triage Stage: | Unreviewed → Accepted |
comment:2 by , 9 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 , 9 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:4 by , 8 years ago
| Owner: | changed from to |
|---|
comment:5 by , 8 years ago
| Has patch: | set |
|---|
Added a PR where I've tried to replace and rephrase the incorrect/misleading examples.
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.