Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #1375: primary_key values with "bad" characters are now escaped…

… in the admin; thanks, Malcom Tredinnick

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2418 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit bc8547aa9dc4710c8fee5d5ee93b395abdb9ff62 1 parent e9e1820
@jacobian jacobian authored
Showing with 41 additions and 1 deletion.
  1. +41 −1 django/contrib/admin/views/main.py
View
42 django/contrib/admin/views/main.py
@@ -42,6 +42,43 @@
class IncorrectLookupParameters(Exception):
pass
+def quote(s):
+ """
+ Ensure that primary key values do not confuse the admin URLs by escaping
+ any '/', '_' and ':' characters. Similar to urllib.quote, except that the
+ quoting is slightly different so that it doesn't get autoamtically
+ unquoted by the web browser.
+ """
+ if type(s) != type(''):
+ return s
+ res = list(s)
+ for i in range(len(res)):
+ c = res[i]
+ if c in ':/_':
+ res[i] = '_%02X' % ord(c)
+ return ''.join(res)
+
+def unquote(s):
+ """
+ Undo the effects of quote(). Based heavily on urllib.unquote().
+ """
+ mychr = chr
+ myatoi = int
+ list = s.split('_')
+ res = [list[0]]
+ myappend = res.append
+ del list[0]
+ for item in list:
+ if item[1:2]:
+ try:
+ myappend(mychr(myatoi(item[:2], 16))
+ + item[2:])
+ except ValueError:
+ myappend('_' + item)
+ else:
+ myappend('_' + item)
+ return "".join(res)
+
def get_javascript_imports(opts, auto_populated_fields, field_sets):
# Put in any necessary JavaScript imports.
js = ['js/core.js', 'js/admin/RelatedObjectLookups.js']
@@ -252,6 +289,7 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
def change_stage(request, app_label, model_name, object_id):
model = models.get_model(app_label, model_name)
+ object_id = unquote(object_id)
if model is None:
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
opts = model._meta
@@ -435,6 +473,7 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
def delete_stage(request, app_label, model_name, object_id):
import sets
model = models.get_model(app_label, model_name)
+ object_id = unquote(object_id)
if model is None:
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
opts = model._meta
@@ -470,6 +509,7 @@ def delete_stage(request, app_label, model_name, object_id):
def history(request, app_label, model_name, object_id):
model = models.get_model(app_label, model_name)
+ object_id = unquote(object_id)
if model is None:
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
action_list = LogEntry.objects.filter(object_id=object_id,
@@ -663,7 +703,7 @@ def get_query_set(self):
return qs
def url_for_result(self, result):
- return "%s/" % getattr(result, self.pk_attname)
+ return "%s/" % quote(getattr(result, self.pk_attname))
def change_list(request, app_label, model_name):
model = models.get_model(app_label, model_name)
Please sign in to comment.
Something went wrong with that request. Please try again.