Code

Ticket #11191: 11191.4.diff

File 11191.4.diff, 3.8 KB (added by SmileyChris, 5 years ago)
Line 
1Index: django/contrib/admin/options.py
2===================================================================
3--- django/contrib/admin/options.py     (revision 11017)
4+++ django/contrib/admin/options.py     (working copy)
5@@ -6,7 +6,7 @@
6 from django.contrib.admin import widgets
7 from django.contrib.admin import helpers
8 from django.contrib.admin.util import unquote, flatten_fieldsets, get_deleted_objects, model_ngettext, model_format_dict
9-from django.core.exceptions import PermissionDenied
10+from django.core.exceptions import PermissionDenied, ValidationError
11 from django.db import models, transaction
12 from django.db.models.fields import BLANK_CHOICE_DASH
13 from django.http import Http404, HttpResponse, HttpResponseRedirect
14@@ -347,6 +347,20 @@
15         defaults.update(kwargs)
16         return modelform_factory(self.model, **defaults)
17 
18+    def get_object(self, request, object_id):
19+        """
20+        Returns an instance matching the primary key provided. ``None``  is
21+        returned if no match is found (or the object_id failed validation
22+        against the primary key field).
23+        """
24+        queryset = self.queryset(request)
25+        model = queryset.model
26+        try:
27+            object_id = model._meta.pk.to_python(object_id)
28+            return queryset.get(pk=object_id)
29+        except (model.DoesNotExist, ValidationError):
30+            return None
31+
32     def get_changelist_form(self, request, **kwargs):
33         """
34         Returns a Form class for use in the Formset on the changelist page.
35@@ -788,13 +802,7 @@
36         model = self.model
37         opts = model._meta
38 
39-        try:
40-            obj = self.queryset(request).get(pk=unquote(object_id))
41-        except model.DoesNotExist:
42-            # Don't raise Http404 just yet, because we haven't checked
43-            # permissions yet. We don't want an unauthenticated user to be able
44-            # to determine whether a given object exists.
45-            obj = None
46+        obj = self.get_object(request, unquote(object_id))
47 
48         if not self.has_change_permission(request, obj):
49             raise PermissionDenied
50@@ -988,13 +996,7 @@
51         opts = self.model._meta
52         app_label = opts.app_label
53 
54-        try:
55-            obj = self.queryset(request).get(pk=unquote(object_id))
56-        except self.model.DoesNotExist:
57-            # Don't raise Http404 just yet, because we haven't checked
58-            # permissions yet. We don't want an unauthenticated user to be able
59-            # to determine whether a given object exists.
60-            obj = None
61+        obj = self.get_object(request, unquote(object_id))
62 
63         if not self.has_delete_permission(request, obj):
64             raise PermissionDenied
65Index: tests/regressiontests/admin_views/tests.py
66===================================================================
67--- tests/regressiontests/admin_views/tests.py  (revision 11017)
68+++ tests/regressiontests/admin_views/tests.py  (working copy)
69@@ -63,11 +63,20 @@
70 
71     def testBasicEditGet(self):
72         """
73-        A smoke test to ensureGET on the change_view works.
74+        A smoke test to ensure GET on the change_view works.
75         """
76         response = self.client.get('/test_admin/%s/admin_views/section/1/' % self.urlbit)
77         self.failUnlessEqual(response.status_code, 200)
78 
79+    def testBasicEditGetStringPK(self):
80+        """
81+        A smoke test to ensure GET on the change_view works (returns an HTTP
82+        404 error, see #11191) when passing a string as the PK argument for a
83+        model with an integer PK field.
84+        """
85+        response = self.client.get('/test_admin/%s/admin_views/section/abc/' % self.urlbit)
86+        self.failUnlessEqual(response.status_code, 404)
87+
88     def testBasicAddPost(self):
89         """
90         A smoke test to ensure POST on add_view works.