From 3b6395370480f44f180c6287e70ea569cd20f0d4 Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Sun, 31 Aug 2008 20:11:11 +0000 Subject: [PATCH] Fixed #6967: `ModelForm`s now validate choices. Thanks, mattmcc -- the failing test helped quite a bit. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8772 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/models/fields/__init__.py | 8 ++++++- tests/modeltests/model_forms/models.py | 29 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 4ddf901ea56..ce5ed343b0b 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -305,7 +305,13 @@ class Field(object): "Returns a django.forms.Field instance for this database Field." defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text} if self.choices: - defaults['widget'] = forms.Select(choices=self.get_choices(include_blank=self.blank or not (self.has_default() or 'initial' in kwargs))) + form_class = forms.TypedChoiceField + include_blank = self.blank or not (self.has_default() or 'initial' in kwargs) + defaults['choices'] = self.get_choices(include_blank=include_blank) + defaults['coerce'] = self.to_python + if self.null: + defaults['empty_value'] = None + kwargs.pop('max_length', None) if self.has_default(): defaults['initial'] = self.get_default() defaults.update(kwargs) diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py index 0ea20751d98..5f714fbedb7 100644 --- a/tests/modeltests/model_forms/models.py +++ b/tests/modeltests/model_forms/models.py @@ -27,6 +27,12 @@ ARTICLE_STATUS = ( (3, 'Live'), ) +ARTICLE_STATUS_CHAR = ( + ('d', 'Draft'), + ('p', 'Pending'), + ('l', 'Live'), +) + class Category(models.Model): name = models.CharField(max_length=20) slug = models.SlugField(max_length=20) @@ -111,6 +117,9 @@ class CommaSeparatedInteger(models.Model): def __unicode__(self): return self.field +class ArticleStatus(models.Model): + status = models.CharField(max_length=2, choices=ARTICLE_STATUS_CHAR, blank=True, null=True) + __test__ = {'API_TESTS': """ >>> from django import forms >>> from django.forms.models import ModelForm, model_to_dict @@ -1123,4 +1132,24 @@ u'1,,2' >>> f.clean('1') u'1' +# Choices on CharField and IntegerField + +>>> class ArticleForm(ModelForm): +... class Meta: +... model = Article +>>> f = ArticleForm() +>>> f.fields['status'].clean('42') +Traceback (most recent call last): +... +ValidationError: [u'Select a valid choice. 42 is not one of the available choices.'] + +>>> class ArticleStatusForm(ModelForm): +... class Meta: +... model = ArticleStatus +>>> f = ArticleStatusForm() +>>> f.fields['status'].clean('z') +Traceback (most recent call last): +... +ValidationError: [u'Select a valid choice. z is not one of the available choices.'] + """}