Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django ModelForm Validation

Trying to solve an interesting problem right now.

I have a Django model with an image field that's not required, but is set to a default value when a new model instance is created.

class Product(models.Model):
    image = models.ImageField(upload_to='/image/directory/', default='/default/image/path/', blank=True)

I also have a ModelForm based on that model, that includes the image field, and that has some custom validation.

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ('image',)

    def clean_image(self):
        image = self.cleaned_data.get('image', False)
        if image:
            # validate image
        return None

The problem is that per the docs, calling is_valid() on a ModelForm triggers model validation in addition to form validation, so when a user submits the model form without an image, my custom form validation code attempts to validate the default model image, rather than just doing nothing as it's supposed to.

How do I get it to not do anything unless the form itself has a value for the image field?

like image 341
rolling stone Avatar asked Oct 09 '12 19:10

rolling stone


1 Answers

Just solved it in pretty simple way. Adding the answer here in case it's helpful to anyone else.

The Django docs state that

...a model form instance bound to a model object will contain a self.instance attribute that gives model form methods access to that specific model instance.

So rather than check if the ModelForm has an image value, I just check whether the image value has changed from the saved instance. The form validation now looks like this:

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ('image',)

    def clean_image(self):
        image = self.cleaned_data.get('image', False)
        if not self.instance.image == image:
            # validate image
        return None

Problem solved!

like image 97
rolling stone Avatar answered Sep 20 '22 19:09

rolling stone