diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 134effc74e..2c7ac5c794 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 ' %s' % escape(truncate_words(obj, 14)) + except (ValueError, self.rel.to.DoesNotExist): return '' - return ' %s' % 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 607ac455fe..cf465ad30c 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -1006,7 +1006,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 diff --git a/tests/regressiontests/admin_widgets/tests.py b/tests/regressiontests/admin_widgets/tests.py index fd0c25ca1a..c445644335 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.')