diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-11-29 16:32:18 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-11-29 16:32:18 +0000 |
| commit | d0f5a58fbd73e1a9ccef405e16ac070787e98fd4 (patch) | |
| tree | ce29f623565f86138d038e64694b8355730f738c | |
| parent | a4ea8d4e939295178b593ebeaf15269b658e8a6a (diff) | |
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
| -rw-r--r-- | AUTHORS | 1 | ||||
| -rw-r--r-- | django/db/models/fields/__init__.py | 2 | ||||
| -rw-r--r-- | docs/newforms.txt | 18 | ||||
| -rw-r--r-- | tests/modeltests/model_forms/models.py | 73 |
4 files changed, 88 insertions, 6 deletions
@@ -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> diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index b0dd55e3b9..ddf695816e 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -392,7 +392,7 @@ class Field(object): "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) diff --git a/docs/newforms.txt b/docs/newforms.txt index 593e9216d7..5feb2e6a02 100644 --- a/docs/newforms.txt +++ b/docs/newforms.txt @@ -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()`` diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py index e4e230c98d..9b0126ff4f 100644 --- a/tests/modeltests/model_forms/models.py +++ b/tests/modeltests/model_forms/models.py @@ -30,6 +30,23 @@ ARTICLE_STATUS = ( (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) @@ -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 @@ -592,4 +615,54 @@ ValidationError: [u'Select a valid choice. 4 is not one of the available choices 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> """} |
