From 5663258de13975e28406233328a9e51c8bc1b768 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Sun, 10 May 2009 07:44:27 +0000 Subject: [PATCH] Fixed #10792 -- Ensured that ModelChoiceFields don't provide an empty option when the underlying field has blank=False and there is a default value available. Thanks to carljm for the report and patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10729 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/forms/models.py | 5 ++++- docs/ref/forms/fields.txt | 4 ++++ tests/regressiontests/forms/models.py | 26 ++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/django/forms/models.py b/django/forms/models.py index 3648a45b65..ce75bdcc3b 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -896,7 +896,10 @@ class ModelChoiceField(ChoiceField): def __init__(self, queryset, empty_label=u"---------", cache_choices=False, required=True, widget=None, label=None, initial=None, help_text=None, to_field_name=None, *args, **kwargs): - self.empty_label = empty_label + if required and (initial is not None): + self.empty_label = None + else: + self.empty_label = empty_label self.cache_choices = cache_choices # Call Field instead of ChoiceField __init__() because we don't need diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt index 63ac707acf..e532971179 100644 --- a/docs/ref/forms/fields.txt +++ b/docs/ref/forms/fields.txt @@ -786,6 +786,10 @@ example:: # No empty label field2 = forms.ModelChoiceField(queryset=..., empty_label=None) + Note that if a ``ModelChoiceField`` is required and has a default + initial value, no empty choice is created (regardless of the value + of ``empty_label``). + ``ModelMultipleChoiceField`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/regressiontests/forms/models.py b/tests/regressiontests/forms/models.py index 472a39d35e..3b47b50b00 100644 --- a/tests/regressiontests/forms/models.py +++ b/tests/regressiontests/forms/models.py @@ -24,6 +24,17 @@ class ChoiceModel(models.Model): """For ModelChoiceField and ModelMultipleChoiceField tests.""" name = models.CharField(max_length=10) +class ChoiceOptionModel(models.Model): + """Destination for ChoiceFieldModel's ForeignKey. + Can't reuse ChoiceModel because error_message tests require that it have no instances.""" + name = models.CharField(max_length=10) + +class ChoiceFieldModel(models.Model): + """Model with ForeignKey to another model, for testing ModelForm + generation with ModelChoiceField.""" + choice = models.ForeignKey(ChoiceOptionModel, blank=False, + default=lambda: ChoiceOptionModel.objects.all()[0]) + class FileModel(models.Model): file = models.FileField(storage=temp_storage, upload_to='tests') @@ -105,4 +116,19 @@ u'class default value' >>> obj.def_date datetime.date(1999, 3, 2) >>> shutil.rmtree(temp_storage_location) + +In a ModelForm with a ModelChoiceField, if the model's ForeignKey has blank=False and a default, +no empty option is created (regression test for #10792). + +First we need at least one instance of ChoiceOptionModel: + +>>> ChoiceOptionModel.objects.create(name='default') + + +>>> class ChoiceFieldForm(ModelForm): +... class Meta: +... model = ChoiceFieldModel +>>> list(ChoiceFieldForm().fields['choice'].choices) +[(1, u'ChoiceOptionModel object')] + """}