Browse files

Fixed #4653 -- Improved the logic to decide when to include (and sel…

…ect as

initial value) the blank choice for a model field with choices. Thanks to
Ilya Semenov for persisting with this.

git-svn-id: bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
malcolmt committed Nov 29, 2007
1 parent a4ea8d4 commit d0f5a58fbd73e1a9ccef405e16ac070787e98fd4
Showing with 88 additions and 6 deletions.
  1. +1 −0 AUTHORS
  2. +1 −1 django/db/models/fields/
  3. +13 −5 docs/newforms.txt
  4. +73 −0 tests/modeltests/model_forms/
@@ -273,6 +273,7 @@ answer newbie questions, and generally made Django that much better:
Vinay Sajip <>
David Schein
+ Ilya Semenov <>
John Shaffer <>
Pete Shinners <>
@@ -392,7 +392,7 @@ def formfield(self, form_class=forms.CharField, **kwargs):
"Returns a django.newforms.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())
+ defaults['widget'] = forms.Select(choices=self.get_choices(include_blank=self.blank or not (self.has_default() or 'initial' in kwargs)))
if self.has_default():
defaults['initial'] = self.get_default()
@@ -1849,7 +1849,11 @@ In addition, each generated form field has attributes set as follows:
* If the model field has ``choices`` set, then the form field's ``widget``
will be set to ``Select``, with choices coming from the model field's
- ``choices``.
+ ``choices``. The choices will normally include the blank choice which is
+ selected by default. If the field is required, this forces the user to
+ make a selection. The blank choice will not be included if the model
+ field has ``blank=False`` and an explicit ``default`` value (the
+ ``default`` value will be initially selected instead).
Finally, note that you can override the form field used for a given model
field. See "Overriding the default field types" below.
@@ -2095,10 +2099,14 @@ instance instead of a model class::
# Instantiate the form.
>>> f = AuthorForm()
-When a form created by ``form_for_instance()`` is created, the initial
-data values for the form fields are drawn from the instance. However,
-this data is not bound to the form. You will need to bind data to the
-form before the form can be saved.
+When a form created by ``form_for_instance()`` is created, the initial data
+values for the form fields are drawn from the instance. However, this data is
+not bound to the form. You will need to bind data to the form before the form
+can be saved.
+Unlike ``form_for_model()``, a choice field in form created by
+``form_for_instance()`` will not include the blank choice if the respective
+model field has ``blank=False``. The initial choice is drawn from the instance.
When you call ``save()`` on a form created by ``form_for_instance()``,
the database instance will be updated. As in ``form_for_model()``, ``save()``
@@ -30,6 +30,23 @@
(3, 'Live'),
+ ('left', 'Left steering wheel'),
+ ('right', 'Right steering wheel'),
+ ('gas', 'Gasoline'),
+ ('diesel', 'Diesel'),
+ ('other', 'Other'),
+ ('at', 'Automatic'),
+ ('mt', 'Manual'),
+ ('cvt', 'CVT'),
class Category(models.Model):
name = models.CharField(max_length=20)
slug = models.SlugField(max_length=20)
@@ -70,6 +87,12 @@ class PhoneNumber(models.Model):
def __unicode__(self):
+class Car(models.Model):
+ name = models.CharField(max_length=50)
+ steering = models.CharField(max_length=5, choices=STEERING_TYPE, default='left')
+ fuel = models.CharField(max_length=10, choices=FUEL_TYPE)
+ transmission = models.CharField(max_length=3, choices=TRANSMISSION_TYPE, blank=True, help_text='Leave empty if not applicable.')
__test__ = {'API_TESTS': """
>>> from django.newforms import form_for_model, form_for_instance, save_instance, BaseForm, Form, CharField
>>> import datetime
@@ -592,4 +615,54 @@ def __unicode__(self):
>>> f.cleaned_data
{'phone': u'312-555-1212', 'description': u'Assistance'}
+# form_for_* blank choices ####################################################
+Show the form for a new Car. Note that steering field doesn't include the blank choice,
+because the field is obligatory and has an explicit default.
+>>> CarForm = form_for_model(Car)
+>>> f = CarForm(auto_id=False)
+>>> print f
+<tr><th>Name:</th><td><input type="text" name="name" maxlength="50" /></td></tr>
+<tr><th>Steering:</th><td><select name="steering">
+<option value="left" selected="selected">Left steering wheel</option>
+<option value="right">Right steering wheel</option>
+<tr><th>Fuel:</th><td><select name="fuel">
+<option value="" selected="selected">---------</option>
+<option value="gas">Gasoline</option>
+<option value="diesel">Diesel</option>
+<option value="other">Other</option>
+<tr><th>Transmission:</th><td><select name="transmission">
+<option value="" selected="selected">---------</option>
+<option value="at">Automatic</option>
+<option value="mt">Manual</option>
+<option value="cvt">CVT</option>
+</select><br />Leave empty if not applicable.</td></tr>
+Create a Car, and display the form for modifying it. Note that now the fuel
+selector doesn't include the blank choice as well, since the field is
+obligatory and can not be changed to be blank.
+>>> honda = Car(name='Honda Accord Wagon', steering='right', fuel='gas', transmission='at')
+>>> HondaForm = form_for_instance(honda)
+>>> f = HondaForm(auto_id=False)
+>>> print f
+<tr><th>Name:</th><td><input type="text" name="name" value="Honda Accord Wagon" maxlength="50" /></td></tr>
+<tr><th>Steering:</th><td><select name="steering">
+<option value="left">Left steering wheel</option>
+<option value="right" selected="selected">Right steering wheel</option>
+<tr><th>Fuel:</th><td><select name="fuel">
+<option value="gas" selected="selected">Gasoline</option>
+<option value="diesel">Diesel</option>
+<option value="other">Other</option>
+<tr><th>Transmission:</th><td><select name="transmission">
+<option value="">---------</option>
+<option value="at" selected="selected">Automatic</option>
+<option value="mt">Manual</option>
+<option value="cvt">CVT</option>
+</select><br />Leave empty if not applicable.</td></tr>

0 comments on commit d0f5a58

Please sign in to comment.