user3599803
user3599803

Reputation: 7044

django model forms cant change field value in clean()

I have a simple model form, to which I've added a simple checkbox:

class OrderForm(forms.ModelForm):
   more_info = models.BooleanField(widget=forms.CheckboxInput())

   def clean(self):
        if 'more_info' not in self.cleaned_data:
             self.instance.details = ""
   class Meta:
        model = Order
        fields = ('details', 'address',  ) # more fields

But this does not work and the 'details' fields is still updated by the user value even if the checkbox is not selected (and the if block is executed, debugged). I've also tried changing self.cleaned_data['details'] instead of self.instance.details but it does not work either.

This is not so important, by in the client side I have a simple javascript code which hide/show the details field if the checkbox is selected.

Upvotes: 0

Views: 1893

Answers (2)

Tiny Instance
Tiny Instance

Reputation: 2671

Instead of updating cleaned_data, try overriding the save method instead

def save(self, force_insert=False, force_update=False, commit=True, *args, **kwargs):
    order = super(OrderForm, self).save(commit=False)
    if not self.cleaned_data.get('more_info', False):
         order.details = ""
    if commit:
        order.save()
    return order

Additionally, if you want to use the clean method you need to call super's clean first.

def clean(self):
    cleaned_data = super(BailiffAddForm, self).clean()
    if not cleaned_data.get('more_info', False):
        ...
    return cleaned_data

Upvotes: 0

user6718271
user6718271

Reputation: 26

class OrderForm(forms.ModelForm):
    more_info = models.BooleanField(required=False)
    
    def clean(self):
        cleaned_data = super().clean()
        if not cleaned_data['more_info']:
            cleaned_data['details'] = ''
        return cleaned_data

From Customizing validation:

This method [clean()] can return a completely different dictionary if it wishes, which will be used as the cleaned_data.

Also:

  1. CheckboxInput is default widget for BooleanField.

  2. BooleanField note:

    If you want to include a boolean in your form that can be either True or False (e.g. a checked or unchecked checkbox), you must remember to pass in required=False when creating the BooleanField.

Upvotes: 0

Related Questions