Django model form using forms.ModelMultipleChoiceField
Asked Answered
R

1

6

I have a ModelForm in my Django app that uses a forms.ModelMultipleChoiceField, which displays as a forms.CheckboxSelectMultiple widget on the form. This ModelForm is used to select/de-select values for a many-to-many relation. Here's the problem: when you uncheck all of the checkboxes and save the form, it doesn't save. If you uncheck all but 1, it does save properly.

Are there any tricks I'm missing here about model forms and many-to-many relations? Am I encountering a bug? I'm new to Django. Thanks in advance.

Custom Field:

class NetworkMessageChoiceField(forms.ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        return obj.display_message    

Model Form:

class MessageTemplateForm(forms.ModelForm):
    network_messages = NetworkMessageChoiceField(queryset=NetworkMessageTemplate.objects, 
                                             widget=forms.CheckboxSelectMultiple())        
    class Meta:
        model = UserProfile
        fields = ('network_messages',)

View that saves form:

def save_message_templates(request, extra_context=dict()):
    try:
        profile_obj = request.user.get_profile()
    except ObjectDoesNotExist:
        profile_obj = UserProfile(user=request.user)

    if request.method == 'POST':
        form = MessageTemplateForm(request.POST, instance=profile_obj)
        if form.is_valid():
            form.save()
            return redirect('/')

    return index(request, message_template_form=form)

Edit:

My form field was missing Required=False.

class MessageTemplateForm(forms.ModelForm):
    network_messages = NetworkMessageChoiceField(queryset=NetworkMessageTemplate.objects, 
                                                 widget=forms.CheckboxSelectMultiple(),
                                                 required=False)        
    class Meta:
        model = UserProfile
        fields = ('network_messages',)
Retro answered 4/2, 2010 at 2:51 Comment(0)
R
0

You didn't paste what your model looks like, so I am guessing that network_messages field in your model is required. If that is the case, then when you attempt to submit the form with the value of that field as NULL (empty), then form.is_valid() is not returning True and therefore your form.save() is never being executed.

Have you tried executing this stuff from an interactive shell, instantiating the form and attempting to manually save() it?

Revis answered 4/2, 2010 at 2:58 Comment(2)
Thank you! That was completely the answer. I just figured it out after posting my question. I was missing Required=False on my form field! class MessageTemplateForm(forms.ModelForm): network_messages = NetworkMessageChoiceField(queryset=NetworkMessageTemplate.objects, widget=forms.CheckboxSelectMultiple(), required=False) class Meta: model = UserProfile fields = ('network_messages',)Retro
Excellent! Glad to be of service.Revis

© 2022 - 2024 — McMap. All rights reserved.