Kaydet (Commit) d0f5a58f authored tarafından Malcolm Tredinnick's avatar Malcolm Tredinnick

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
üst a4ea8d4e
...@@ -273,6 +273,7 @@ answer newbie questions, and generally made Django that much better: ...@@ -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>
......
...@@ -392,7 +392,7 @@ class Field(object): ...@@ -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)
......
...@@ -1849,7 +1849,11 @@ In addition, each generated form field has attributes set as follows: ...@@ -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:: ...@@ -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()``
......
...@@ -30,6 +30,23 @@ ARTICLE_STATUS = ( ...@@ -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): ...@@ -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 ...@@ -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>
"""} """}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment