mirror of https://github.com/django/django.git
[3.0.x] Fixed #30014 -- Fixed ModelChoiceField validation when initial value is a model instance.
Thanks Carlton Gibson for reviews.
Backport of e7cdb0cd7e
from master
This commit is contained in:
parent
82ba905db3
commit
651299e1ef
|
@ -1248,6 +1248,8 @@ class ModelChoiceField(ChoiceField):
|
||||||
return None
|
return None
|
||||||
try:
|
try:
|
||||||
key = self.to_field_name or 'pk'
|
key = self.to_field_name or 'pk'
|
||||||
|
if isinstance(value, self.queryset.model):
|
||||||
|
value = getattr(value, key)
|
||||||
value = self.queryset.get(**{key: value})
|
value = self.queryset.get(**{key: value})
|
||||||
except (ValueError, TypeError, self.queryset.model.DoesNotExist):
|
except (ValueError, TypeError, self.queryset.model.DoesNotExist):
|
||||||
raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
|
raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
|
||||||
|
|
|
@ -55,9 +55,18 @@ class ModelChoiceFieldTests(TestCase):
|
||||||
with self.assertRaisesMessage(ValidationError, msg):
|
with self.assertRaisesMessage(ValidationError, msg):
|
||||||
f.clean(c4.id)
|
f.clean(c4.id)
|
||||||
|
|
||||||
|
def test_clean_model_instance(self):
|
||||||
|
f = forms.ModelChoiceField(Category.objects.all())
|
||||||
|
self.assertEqual(f.clean(self.c1), self.c1)
|
||||||
|
# An instance of incorrect model.
|
||||||
|
msg = "['Select a valid choice. That choice is not one of the available choices.']"
|
||||||
|
with self.assertRaisesMessage(ValidationError, msg):
|
||||||
|
f.clean(Book.objects.create())
|
||||||
|
|
||||||
def test_clean_to_field_name(self):
|
def test_clean_to_field_name(self):
|
||||||
f = forms.ModelChoiceField(Category.objects.all(), to_field_name='slug')
|
f = forms.ModelChoiceField(Category.objects.all(), to_field_name='slug')
|
||||||
self.assertEqual(f.clean(self.c1.slug), self.c1)
|
self.assertEqual(f.clean(self.c1.slug), self.c1)
|
||||||
|
self.assertEqual(f.clean(self.c1), self.c1)
|
||||||
|
|
||||||
def test_choices(self):
|
def test_choices(self):
|
||||||
f = forms.ModelChoiceField(Category.objects.filter(pk=self.c1.id), required=False)
|
f = forms.ModelChoiceField(Category.objects.filter(pk=self.c1.id), required=False)
|
||||||
|
@ -194,6 +203,16 @@ class ModelChoiceFieldTests(TestCase):
|
||||||
field = forms.ModelChoiceField(Author.objects.all(), disabled=True)
|
field = forms.ModelChoiceField(Author.objects.all(), disabled=True)
|
||||||
self.assertIs(field.has_changed('x', 'y'), False)
|
self.assertIs(field.has_changed('x', 'y'), False)
|
||||||
|
|
||||||
|
def test_disabled_modelchoicefield_initial_model_instance(self):
|
||||||
|
class ModelChoiceForm(forms.Form):
|
||||||
|
categories = forms.ModelChoiceField(
|
||||||
|
Category.objects.all(),
|
||||||
|
disabled=True,
|
||||||
|
initial=self.c1,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(ModelChoiceForm(data={'categories': self.c1.pk}).is_valid())
|
||||||
|
|
||||||
def test_disabled_multiplemodelchoicefield(self):
|
def test_disabled_multiplemodelchoicefield(self):
|
||||||
class ArticleForm(forms.ModelForm):
|
class ArticleForm(forms.ModelForm):
|
||||||
categories = forms.ModelMultipleChoiceField(Category.objects.all(), required=False)
|
categories = forms.ModelMultipleChoiceField(Category.objects.all(), required=False)
|
||||||
|
|
Loading…
Reference in New Issue