Opened 12 years ago

Last modified 2 weeks ago

#22226 assigned Bug

Reversing admin URLs requires undocumented filter admin_urlquote.

Reported by: Mattias Linnap Owned by: Sidharth Dusanapudi
Component: contrib.admin Version: dev
Severity: Normal Keywords:
Cc: Ülgen Sarıkavak, Sidharth Dusanapudi Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have a model with a text primary key:

class CharKey(models.Model):
    id = models.CharField(max_length=20, primary_key=True)

Reversing admin URLs as described in https://docs.djangoproject.com/en/dev/ref/contrib/admin/#reversing-admin-urls sometimes breaks depending on the characters in the key.

The admin pages call django.contrib.admin.utils.unquote() on the primary key received in the URL. Internally, admin templates escape the object URLs with for example

{% url opts|admin_urlname:'change' original.pk|admin_urlquote %}

The links obtained from the basic reverse(), as used in the documentation, do not work:

reverse('admin:key_charkey_change', args=(c.id,))

as they fail to quote special charcters like the underscore "_". Instead, the page linking to the admin has to use django.contrib.admin.utils.quote() on the argument to reverse(), or the corresponding template filter in a template.

The issue is surprisingly confusing because it seems that browsers like Chrome auto-escape most, but not all special characters in a format accepted and decoded by unquote(): for example, characters like $%^&*() work just fine without quote() in the code, but for example the underscore does not. As a result the admin URLs without quoting work fine even with funny characters in the primary key, unless one of the few exceptional characters are used.

As a workaround, documenting the mandatory use of admin_urlquote template filter and updating the examples might be enough.
However, I wonder if there are more general fixes to reverse() possible? This seems like an issue that would come up in custom, non-admin URLs as well.

I originally reported this in the comments of https://code.djangoproject.com/ticket/18381, but created a separate issue as requested. The behaviour of this ticket is present in the current django master.

Change History (4)

comment:1 by Aymeric Augustin, 12 years ago

Triage Stage: UnreviewedAccepted

comment:2 by Ülgen Sarıkavak, 2 years ago

Cc: Ülgen Sarıkavak added

comment:3 by Sidharth Dusanapudi, 2 weeks ago

Has patch: set

PR available: https://github.com/django/django/pull/21098

Clarifies the admin docs to use quote() in Python and admin_urlquote in templates when reversing URLs with object IDs.

comment:4 by Sidharth Dusanapudi, 2 weeks ago

Cc: Sidharth Dusanapudi added
Owner: changed from nobody to Sidharth Dusanapudi
Status: newassigned
Note: See TracTickets for help on using tickets.
Back to Top