Django ModelForm CheckBox Widget

22,703

Solution 1

In such a case, the easiest way is to put the choices into a separate model and then use a ManyToMany relationship. After that, you simply override the ModelForm's widget for that field to use forms.CheckboxSelectMultiple and Django will automatically do the right thing. If you insist to use a CharField, you'll probably have to do something like this snippet.

@ 2. comment: how are you overriding the widget? This is how I do it and it works flawlessly:

class SomeModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(SomeModelForm, self).__init__(*args, **kwargs)
        self.fields['some_field'].widget = forms.CheckboxSelectMultiple()

Solution 2

I've just started to look into widgets assignment with ModelForms. In a lot of examples I've seen, piquadrat's included, the Form's __ init __ method is overridden.

I find this a little confusing, and just overriding the desired field is more natural for me:

class SomeModelForm(forms.ModelForm):
    some_field = forms.CharField(choices=MEDIA_CHOICES,
                                 widget=forms.CheckboxSelectMultiple)
    class Meta:
        model=SomeModel

Note: I'm using Django 1.1.

Share:
22,703
user1483801
Author by

user1483801

Currently working at Imaginary Landscape in Chicago, IL as a Python/Django developer. I generally release all my side projects as open source. You can find them at: http://github.com/f4nt/djtracker http://github.com/f4nt/django-yaba I also try to contribute back to open source projects when possible. I've made some (generally small) commits to the following: http://github.com/digi604/django-cms-2.0 http://github.com/imagescape/iscape-djangonews http://github.com/imagescape/iscape-jobboard http://github.com/Poromenos/apache-config http://github.com/thauber/django-schedule

Updated on December 07, 2020

Comments

  • user1483801
    user1483801 over 3 years

    I'm currently have an issue, and likely overlooking something very trivial. I have a field in my model that should allow for multiple choices via a checkbox form (it doesn't have to be a checkbox in the admin screen, just in the form area that the end-user will see). Currently I have the field setup like so:

    # Type of Media
    MEDIA_CHOICES = (
        ('1', 'Magazine'),
        ('2', 'Radio Station'),
        ('3', 'Journal'),
        ('4', 'TV Station'),
        ('5', 'Newspaper'),
        ('6', 'Website'),
    )
    media_choice = models.CharField(max_length=25,
        choices=MEDIA_CHOICES)
    

    I need to take that and make a checkbox selectable field in a form out of it though. When I create a ModelForm, it wants to do a drop down box. So I naturally overrode that field, and I get my checkbox that I want. However, when the form's submitted, it would appear that nothing useful is saved when I look at the admin screen. The database does however show that I have a number of things selected, which is a positive sign. However, how can I get that to reflect in the admin screen properly?

    Edit: FWIW I'll gladly accept documentation links as answers, because it would seem I'm just glossing over something obvious.

  • user1483801
    user1483801 over 14 years
    Thanks for the tip. Didn't want to use ManyToMany because I'd be creating about 6 models for information that will always be static. Seemed unnecessary.
  • user1483801
    user1483801 over 14 years
    Also, fwiw, that doesn't seem to work. The field renders blank when I use CheckBoxSelectMultiple form. If I use MultipleChoiceField, with the Checkbox widget that sorta works, but only if I supply the form with a list of choices. Then I have to go mapping data back with overriden clean function. Maybe that's the correct way, but it "feels" wrong, and typically when something "feels" wrong, it is. Just trying to verify I'm not overdoing it here.
  • user1483801
    user1483801 over 14 years
    Well I wasn't doing it right, so thanks for setting me straight there, however now I have this: in Models.py: media_type = models.ManyToManyField(MediaChoice) in Forms.py: def __init__(self, *args, **kwargs): super(MediaContactForm, self).__init__(*args, **kwargs) self.fields['media_type'].widget = forms.CheckboxSelectMultiple()
  • user1483801
    user1483801 over 14 years
    well I can see the choices showing up properly if I dump out the contents of the form. There must be something wrong in my templates I guess. Certain widgets show fine, but this one doesn't. Not sure why yet.
  • Benjamin Wohlwend
    Benjamin Wohlwend over 14 years
    How do you render the form? Have you tried something like this? <table>{{ form.as_table }}</table>
  • user1483801
    user1483801 over 14 years
    The HTML of the form is rather customized, so I have to output each field individually. The odd part is that if I don't override it, it works fine. I override it, and it doesn't render, but the choices are there.
  • phunehehe
    phunehehe over 13 years
    Thanks for the last comment, I wish it came up to the top