Opened 3 years ago

Closed 17 months ago

#18381 closed Bug (fixed)

Underscore in CharField primary key breaks the admin "view on site" link

Reported by: dappawit Owned by: apollo13
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:

  1. I created a new project and enabled the Admin, both in settings.py and in urls.py.
  2. 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)
  1. I added 'testapp' to the INSTALLED_APPS setting.
  2. 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'.
  3. Using the 'abc123' instance in the Admin site:
    1. it is at the Admin url of /admin/testapp/mymodel/abc123/, as expected.
    2. the view on site link points to /admin/r/8/abc123/, as expected.
    3. 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.)
  4. Using the 'abc_123' instance in the Admin site:
    1. it is at the Admin url of /admin/testapp/mymodel/abc_5F123/
    2. the view on site link points to /admin/r/8/abc_5F123/,
    3. 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".
    4. manually entering the url /admin/r/8/abc_123/ (note: without the '5F') work as expected.
    5. 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.

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 Changed 3 years ago by apollo13

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

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.

comment:2 Changed 3 years ago by apollo13

  • Owner changed from nobody to apollo13

comment:3 Changed 3 years ago by apollo13

comment:4 Changed 3 years ago by dhepper

  • Triage Stage changed from Accepted to Ready for checkin

comment:5 Changed 3 years ago by Aymeric Augustin <aymeric.augustin@…>

  • Resolution set to fixed
  • Status changed from new to closed

In [23d230f05833a63e951b8f451ff6c9f570eb3208]:

Merge pull request #123 from apollo13/ticket18381

Fixed #18381 -- Stopped escaping object ids

when passing them to the contenttypes.shortcut view.

Thanks apollo13 for the patch and dhepper for the review.

comment:6 Changed 17 months ago by mattias

  • Resolution fixed deleted
  • Status changed from closed to 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 Changed 17 months ago by mattias

  • Version changed from 1.4 to 1.6

comment:8 Changed 17 months ago by timo

  • Version changed from 1.6 to 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 Changed 17 months ago by timo

  • Resolution set to fixed
  • Status changed from new to closed
Note: See TracTickets for help on using tickets.
Back to Top