summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Plant <L.Plant.98@cantab.net>2009-12-28 14:15:34 +0000
committerLuke Plant <L.Plant.98@cantab.net>2009-12-28 14:15:34 +0000
commit58bf653a26aae6ec466761c5d5933d1a5edfa641 (patch)
treeff908a838e36064e0836f6c9127befcca8114321
parentf1fe7c00e2c5496fd6998965385834f720bb35c2 (diff)
[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
-rw-r--r--django/contrib/admin/options.py32
-rw-r--r--tests/regressiontests/admin_views/tests.py11
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.