Django ClearableFileInput - how to detect whether to delete the file

4k views Asked by At

I'm using Django Crispy Forms for my form with an option to upload an image (ImageField in my Model)

The forms renders as I'd expect, with the checkbox to clear an existing file. However when processing the form submission the 'image-clear' checkbox always gives me a 'None' value.

image_clear = form.cleaned_data.get("image-clear")
print image_clear

In the HTML of the page I notice that the input checkbox doesn't have a value attribute, see:

<input id="image-clear_id" type="checkbox" name="image-clear">

So I wondered if this was the issue, but when I look at the rendering in the Django admin site, the corresponding HTML input field doesn't have a value either - yet it still identifies that the image should be removed.

I should note that if I upload a new image, then this works, it's only the case where I'm removing/clearing the image (and it works in Django admin pages, so assume that means my model definition is ok to allow no image to be attached to the model)

So... in my form processing, how do I detect whether or not the image should be removed or not?

I'm sure I'm missing something simple here - and any help much appreciated.

2

There are 2 answers

0
Serkan On BEST ANSWER

You shouldn't check the checkbox, but check the value of the file input field. If it is False, then you can delete the file. Otherwise it is the uploaded file. See: https://github.com/django/django/blob/339c01fb7552feb8df125ef7e5420dae04fd913f/django/forms/widgets.py#L434

    # False signals to clear any existing value, as opposed to just None
    return False
return upload
0
Alexey Chernov On

Let me add here my code that solved the problem - I decided to put this logic to ModelForm.clean():

class Document(models.Model):
    upload = models.FileField(upload_to=document_name, blank=True)

class DocumentForm(ModelForm):
    def clean(self):
        cleaned_data = super(DocumentForm, self).clean()
        upload = cleaned_data['upload']
        if (upload == False) and self.instance.upload:
            if os.path.isfile(self.instance.upload.path):
                self.instance.upload.delete(False)