Fixed #4653 -- Improved the logic to decide when to include (and select 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
This commit is contained in:
Malcolm Tredinnick 2007-11-29 16:32:18 +00:00
parent a4ea8d4e93
commit d0f5a58fbd
4 changed files with 88 additions and 6 deletions

View File

@ -273,6 +273,7 @@ answer newbie questions, and generally made Django that much better:
Vinay Sajip <vinay_sajip@yahoo.co.uk> Vinay Sajip <vinay_sajip@yahoo.co.uk>
David Schein David Schein
scott@staplefish.com scott@staplefish.com
Ilya Semenov <semenov@inetss.com>
serbaut@gmail.com serbaut@gmail.com
John Shaffer <jshaffer2112@gmail.com> John Shaffer <jshaffer2112@gmail.com>
Pete Shinners <pete@shinners.org> Pete Shinners <pete@shinners.org>

View File

@ -392,7 +392,7 @@ class Field(object):
"Returns a django.newforms.Field instance for this database Field." "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} defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}
if self.choices: 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(): if self.has_default():
defaults['initial'] = self.get_default() defaults['initial'] = self.get_default()
defaults.update(kwargs) defaults.update(kwargs)

View File

@ -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`` * 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 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 Finally, note that you can override the form field used for a given model
field. See "Overriding the default field types" below. field. See "Overriding the default field types" below.
@ -2095,10 +2099,14 @@ instance instead of a model class::
# Instantiate the form. # Instantiate the form.
>>> f = AuthorForm() >>> f = AuthorForm()
When a form created by ``form_for_instance()`` is created, the initial When a form created by ``form_for_instance()`` is created, the initial data
data values for the form fields are drawn from the instance. However, values for the form fields are drawn from the instance. However, this data is
this data is not bound to the form. You will need to bind data to the not bound to the form. You will need to bind data to the form before the form
form before the form can be saved. 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()``, When you call ``save()`` on a form created by ``form_for_instance()``,
the database instance will be updated. As in ``form_for_model()``, ``save()`` the database instance will be updated. As in ``form_for_model()``, ``save()``

View File

@ -30,6 +30,23 @@ ARTICLE_STATUS = (
(3, 'Live'), (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): class Category(models.Model):
name = models.CharField(max_length=20) name = models.CharField(max_length=20)
slug = models.SlugField(max_length=20) slug = models.SlugField(max_length=20)
@ -70,6 +87,12 @@ class PhoneNumber(models.Model):
def __unicode__(self): def __unicode__(self):
return self.phone 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': """ __test__ = {'API_TESTS': """
>>> from django.newforms import form_for_model, form_for_instance, save_instance, BaseForm, Form, CharField >>> from django.newforms import form_for_model, form_for_instance, save_instance, BaseForm, Form, CharField
>>> import datetime >>> import datetime
@ -592,4 +615,54 @@ ValidationError: [u'Select a valid choice. 4 is not one of the available choices
True True
>>> f.cleaned_data >>> f.cleaned_data
{'phone': u'312-555-1212', 'description': u'Assistance'} {'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>
"""} """}