From 58bf653a26aae6ec466761c5d5933d1a5edfa641 Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Mon, 28 Dec 2009 14:15:34 +0000 Subject: [PATCH] [1.1.X] Fixed #11191 - Admin throws 500 instead of 404 for PK of incorrect type Thanks to mmachine for report and test, and Chris Beaven for the patch Backport of r12011 from trunk git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@12012 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/admin/options.py | 32 ++++++++++++---------- tests/regressiontests/admin_views/tests.py | 11 +++++++- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index c7231a2755..21c8a4b277 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -6,7 +6,7 @@ from django.contrib.contenttypes.models import ContentType from django.contrib.admin import widgets from django.contrib.admin import helpers from django.contrib.admin.util import unquote, flatten_fieldsets, get_deleted_objects, model_ngettext, model_format_dict -from django.core.exceptions import PermissionDenied +from django.core.exceptions import PermissionDenied, ValidationError from django.db import models, transaction from django.db.models.fields import BLANK_CHOICE_DASH from django.http import Http404, HttpResponse, HttpResponseRedirect @@ -347,6 +347,20 @@ class ModelAdmin(BaseModelAdmin): defaults.update(kwargs) return modelform_factory(self.model, **defaults) + def get_object(self, request, object_id): + """ + Returns an instance matching the primary key provided. ``None`` is + returned if no match is found (or the object_id failed validation + against the primary key field). + """ + queryset = self.queryset(request) + model = queryset.model + try: + object_id = model._meta.pk.to_python(object_id) + return queryset.get(pk=object_id) + except (model.DoesNotExist, ValidationError): + return None + def get_changelist_form(self, request, **kwargs): """ Returns a Form class for use in the Formset on the changelist page. @@ -795,13 +809,7 @@ class ModelAdmin(BaseModelAdmin): model = self.model opts = model._meta - try: - obj = self.queryset(request).get(pk=unquote(object_id)) - except model.DoesNotExist: - # Don't raise Http404 just yet, because we haven't checked - # permissions yet. We don't want an unauthenticated user to be able - # to determine whether a given object exists. - obj = None + obj = self.get_object(request, unquote(object_id)) if not self.has_change_permission(request, obj): raise PermissionDenied @@ -996,13 +1004,7 @@ class ModelAdmin(BaseModelAdmin): opts = self.model._meta app_label = opts.app_label - try: - obj = self.queryset(request).get(pk=unquote(object_id)) - except self.model.DoesNotExist: - # Don't raise Http404 just yet, because we haven't checked - # permissions yet. We don't want an unauthenticated user to be able - # to determine whether a given object exists. - obj = None + obj = self.get_object(request, unquote(object_id)) if not self.has_delete_permission(request, obj): raise PermissionDenied diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index bdc0c0376d..9535381049 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -65,11 +65,20 @@ class AdminViewBasicTest(TestCase): def testBasicEditGet(self): """ - A smoke test to ensureGET on the change_view works. + A smoke test to ensure GET on the change_view works. """ response = self.client.get('/test_admin/%s/admin_views/section/1/' % self.urlbit) self.failUnlessEqual(response.status_code, 200) + def testBasicEditGetStringPK(self): + """ + A smoke test to ensure GET on the change_view works (returns an HTTP + 404 error, see #11191) when passing a string as the PK argument for a + model with an integer PK field. + """ + response = self.client.get('/test_admin/%s/admin_views/section/abc/' % self.urlbit) + self.failUnlessEqual(response.status_code, 404) + def testBasicAddPost(self): """ A smoke test to ensure POST on add_view works.