Opened 12 years ago
Closed 11 years ago
#18381 closed Bug (fixed)
Underscore in CharField primary key breaks the admin "view on site" link
Reported by: | dappawit | Owned by: | Florian Apolloner |
---|---|---|---|
Component: | contrib.admin | Version: | 1.4 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I have a model in which the primary key is a CharField and the get_absolute_url method is defined. When I create an instance of the model with the primary key containing an underscore "_", the admin links for that object have '5F' (the ASCII hex code for an underscore) after the underscore. For instance, if the primary key was 'abc_123', then the link to the object within the admin would contain 'abc_5F123'. Strangely, these links work just fine. And if you strip out the '5F', the links also work. However, with the '5F' in the URL, the view on site link does not work.
To recreate the bug:
- I created a new project and enabled the Admin, both in settings.py and in urls.py.
- I created an app 'testapp' with the following models.py:
from django.db import models class MyModel(models.Model): id = models.CharField(max_length=100, primary_key=True) def get_absolute_url(self): return '/mymodel/{0}/'.format(self.id)
- I added 'testapp' to the INSTALLED_APPS setting.
- I started the dev server and created two instances of the 'MyModel' model in the admin: one with the primary key 'abc123' and one with the primary key 'abc_123'.
- Using the 'abc123' instance in the Admin site:
- it is at the Admin url of
/admin/testapp/mymodel/abc123/
, as expected. - the view on site link points to
/admin/r/8/abc123/
, as expected. - clicking on the view on site link tries to redirect me to
example.com/mymodel/abc123/
as expected. (I'm actually taken to an IANA page about example.com being a fake domain. But Chrome's developer tools shows that it first tried to redirect me to the example.com URL above.)
- it is at the Admin url of
- Using the 'abc_123' instance in the Admin site:
- it is at the Admin url of
/admin/testapp/mymodel/abc_5F123/
- the view on site link points to
/admin/r/8/abc_5F123/
, - clicking on the view on site link results in a 404 error at the
/admin/r/8/abc_5F123/
url. I get the message: "Content type 8 object abc_5F123 doesn't exist". - manually entering the url
/admin/r/8/abc_123/
(note: without the '5F') work as expected. - manually entering the url
/admin/testapp/mymodel/abc_123/
does not work in this demo, although it worked in the full application where I first encountered the problem.
- it is at the Admin url of
I'd like to be able to use the view on site link even when objects have underscores in their primary keys. Even better would be to also remove the strange '5F' from the admin site URLs, although since they still work it is not absolutely necessary.
Tested with:
- Django 1.4 using SQLite
- both Chrome and Firefox
- Discovered the issue on Linux, then created small test app on Windows.
I hope that makes sense. Thanks.
Change History (9)
comment:1 by , 12 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 12 years ago
Owner: | changed from | to
---|
comment:4 by , 12 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
comment:5 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:6 by , 11 years ago
Resolution: | fixed |
---|---|
Status: | closed → new |
Although this bug was closed fixed 2 years ago, related issues seem still present in the latest stable Django release 1.6.2.
CharField primary keys with underscores are (un)escaped differently in the admin pages, and when reversing admin URLs with django.core.urlresolvers.reverse() or the {% url %} template tag.
The admin pages add "5F" after the underscore in when rendering URLs, but reverse() does not. As a result, links from custom pages into the admin break when the object's primary key contains underscores.
Steps to reproduce:
- Create a model with "id = models.CharField(max_length=100, primary_key=True)" or other similar text primary key field,
- Register the model to the admin site,
- Create a model instance with test_123 as the primary key,
- Visit the admin, and observe admin URLs: they are of the format "/admin/<app>/<model>/test_5F123/"
- Open the shell, and call reverse('admin:app_model_delete', args=['test_123'])
- The URLs returned are of the format "/admin/<app>/<model>/test_123/" - no 5F
- As a result, if these links are embedded in pages, they don't work - the admin page tries to decode the primary key, expects 5F, and does not find the object.
comment:7 by , 11 years ago
Version: | 1.4 → 1.6 |
---|
comment:8 by , 11 years ago
Version: | 1.6 → 1.4 |
---|
Please open a new ticket for related issues, rather than reopening a ticket where the fix has already been released. Thanks!
comment:9 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
The problem is that we pass the escaped object_id into contenttype_views.shortcut -- we either have to unquote there or don't pass the quoted url into it.