Skip to content

Commit

Permalink
Fixed #4653 -- Improved the logic to decide when to include (and sele…
Browse files Browse the repository at this point in the history
…ct as

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


git-svn-id: http://code.djangoproject.com/svn/django/trunk@6733 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
mtredinnick committed Nov 29, 2007
1 parent 963f55b commit c3271f7
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 6 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -273,6 +273,7 @@ answer newbie questions, and generally made Django that much better:
Vinay Sajip <vinay_sajip@yahoo.co.uk>
David Schein
scott@staplefish.com
Ilya Semenov <semenov@inetss.com>
serbaut@gmail.com
John Shaffer <jshaffer2112@gmail.com>
Pete Shinners <pete@shinners.org>
Expand Down
2 changes: 1 addition & 1 deletion django/db/models/fields/__init__.py
Expand Up @@ -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()
defaults.update(kwargs)
Expand Down
18 changes: 13 additions & 5 deletions docs/newforms.txt
Expand Up @@ -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.
Expand Down Expand Up @@ -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()``
Expand Down
73 changes: 73 additions & 0 deletions tests/modeltests/model_forms/models.py
Expand Up @@ -30,6 +30,23 @@
(3, 'Live'),
)

STEERING_TYPE = (
('left', 'Left steering wheel'),
('right', 'Right steering wheel'),
)

FUEL_TYPE = (
('gas', 'Gasoline'),
('diesel', 'Diesel'),
('other', 'Other'),
)

TRANSMISSION_TYPE = (
('at', 'Automatic'),
('mt', 'Manual'),
('cvt', 'CVT'),
)

class Category(models.Model):
name = models.CharField(max_length=20)
slug = models.SlugField(max_length=20)
Expand Down Expand Up @@ -70,6 +87,12 @@ class PhoneNumber(models.Model):
def __unicode__(self):
return self.phone

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
Expand Down Expand Up @@ -592,4 +615,54 @@ def __unicode__(self):
True
>>> 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>
</select></td></tr>
<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>
</select></td></tr>
<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')
>>> honda.save()
>>> 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>
</select></td></tr>
<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>
</select></td></tr>
<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 c3271f7

Please sign in to comment.