From 784b77b46d84e7c7ff94d976982a50670cb5513c Mon Sep 17 00:00:00 2001
From: Chris Adams <chris@improbable.org>
Date: Fri, 10 Sep 2010 11:26:19 -0700
Subject: [PATCH 1/2] Patch for ForeignKeyRawIdWidget error handling

This adds some error handling for invalid (i.e. ValueError-raising)
inputs in raw id fields, where a user may currently enter arbitrary
string values.

See http://code.djangoproject.com/ticket/13149
---
 django/contrib/admin/widgets.py |    6 +++---
 django/forms/models.py          |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index 1d321d0..5832f82 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -154,9 +154,9 @@ class ForeignKeyRawIdWidget(forms.TextInput):
         key = self.rel.get_related_field().name
         try:
             obj = self.rel.to._default_manager.using(self.db).get(**{key: value})
-        except self.rel.to.DoesNotExist:
+            return '&nbsp;<strong>%s</strong>' % escape(truncate_words(obj, 14))
+        except (ValueError, self.rel.to.DoesNotExist):
             return ''
-        return '&nbsp;<strong>%s</strong>' % escape(truncate_words(obj, 14))
 
 class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
     """
@@ -169,7 +169,7 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
     def render(self, name, value, attrs=None):
         attrs['class'] = 'vManyToManyRawIdAdminField'
         if value:
-            value = ','.join([str(v) for v in value])
+            value = ','.join([force_unicode(v) for v in value])
         else:
             value = ''
         return super(ManyToManyRawIdWidget, self).render(name, value, attrs)
diff --git a/django/forms/models.py b/django/forms/models.py
index 8accd61..98a3979 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -987,7 +987,7 @@ class ModelChoiceField(ChoiceField):
         try:
             key = self.to_field_name or 'pk'
             value = self.queryset.get(**{key: value})
-        except self.queryset.model.DoesNotExist:
+        except (ValueError, self.queryset.model.DoesNotExist):
             raise ValidationError(self.error_messages['invalid_choice'])
         return value
 
-- 
1.7.0.2


From efa4d66386fac54b1b6f683e198e448730d62143 Mon Sep 17 00:00:00 2001
From: Chris Adams <chris@improbable.org>
Date: Fri, 10 Sep 2010 12:08:29 -0700
Subject: [PATCH 2/2] Tests for #13149

This adds some basic tests to confirm that incorrect values in M2M
raw_id fields result in form errors rather than unhandled exceptions
---
 tests/regressiontests/admin_widgets/tests.py |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/tests/regressiontests/admin_widgets/tests.py b/tests/regressiontests/admin_widgets/tests.py
index fd0c25c..c445644 100644
--- a/tests/regressiontests/admin_widgets/tests.py
+++ b/tests/regressiontests/admin_widgets/tests.py
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
 from django import forms
 from django.contrib import admin
 from django.contrib.admin import widgets
@@ -151,3 +153,13 @@ class AdminForeignKeyRawIdWidget(DjangoTestCase):
             post_data)
         self.assertContains(response,
             'Select a valid choice. That choice is not one of the available choices.')
+
+    def test_invalid_target_id(self):
+
+        for test_str in ('Iñtërnâtiônàlizætiøn', "1234'", -1234):
+            # This should result in an error message, not a server exception.
+            response = self.client.post('%s/admin_widgets/event/add/' % self.admin_root,
+                {"band": test_str})
+
+            self.assertContains(response,
+                'Select a valid choice. That choice is not one of the available choices.')
-- 
1.7.0.2

