devfeng
devfeng

Reputation: 291

How to remove "None" option in Django ModelForm?

For example, I have a model like this:

class Item(models.Model):
    TYPE_CHOICES = (
        (1, _('type 1')),
        (2, _('type 2')),
    )
    type = models.PositiveSmallIntegerField(max_length=1, choices=TYPE_CHOICES)

And for the form I have:

class ItemModelForm(forms.ModelForm):
    class Meta:
        model = Item
        widget = {
            'type': forms.RadioSelect(),
        }

What I'd like to have is a radio select with 2 options ("type 1" and "type 2"). However, I will have 3 options, "---------", "type 1" and "type 2". The "---------" is for "None" I think, but the "type" field is required in the model, why does the "None" option still show up?

But if I use Form instead:

class ItemForm(forms.Form):
    type = forms.ChoiceField(widget=forms.RadioSelect(), choices=Item.TYPE_CHOICES)

I will have only 2 options, "type 1" and "type 2", which is correct.

I'd like to use ModelForm over standard Form, but don't know how to remove the "---------". Could anybody help me? Thanks.

UPDATE: Thanks guys, just found that it has been answered here.

Looks like I will have to override either the field or method of the ModelForm.

Upvotes: 6

Views: 5834

Answers (5)

Wayne Lambert
Wayne Lambert

Reputation: 606

For anyone that's arriving here from Google for a suitable answer for modern versions of Django and that have a models.py and admin.py setup similar to below.

# models.py

class SampleModel(models.Model):
    SAMPLE_OPTIONS = (
        ('Option 1', 'Option 1'),
        ('Option 2', 'Option 2'),
    )
    ...
    sample_options = models.CharField(
        _('Sample Options'),
        choices=SAMPLE_OPTIONS,
        default='Option 1',
        blank=False,
        max_length=17,
    )
    ...

# admin.py

class SampleAdmin(admin.ModelAdmin):
    ...
    radio_fields = {'sample_options': admin.HORIZONTAL}
    ...

If the blank argument is set to True, there will be 3 options:

  1. None
  2. Option 1
  3. Option 2

If the blank argument is set to False, there will just be the two options:

  1. Option 1
  2. Option 2

Upvotes: 0

user6266095
user6266095

Reputation:

If you have a modelForm, you should overwrite the field in your form with forms.ModelChoiceField() instead of models.ChoiceField() then add the parameters as shown above replacing choices with queryset.

type = forms.ModelChoiceField(widget=forms.RadioSelect(), empty_label=None, queryset=TYPE.objects.all())

Upvotes: 1

frnhr
frnhr

Reputation: 12903

There is a much simpler way, without overriding anything: just add default=1 like so:

type = models.PositiveSmallIntegerField(max_length=1, choices=TYPE_CHOICES, default=1)

Found this in Django source:

           include_blank = (self.blank or
                         not (self.has_default() or 'initial' in kwargs))

Upvotes: 0

balazs
balazs

Reputation: 5788

As I see It's a duplicate of how-to-get-rid-of-the-bogus-choice-generated-by-radioselect-of-django-form

the answer is there, and additional links, hope will help.

EDIT

so maybe if you try this, (i didn't do it, no warranty :) )

widget = {
            'type': forms.RadioSelect(choices=Item.TYPE_CHOICES),
        }

Upvotes: -2

Uku Loskit
Uku Loskit

Reputation: 42040

You should be able to set empty_label to None for this.

type = forms.ChoiceField(widget=forms.RadioSelect(), choices=Item.TYPE_CHOICES, empty_label=None)

Upvotes: 5

Related Questions