0

I'm finding it overly difficult to customize ClearableFileInput as set as the default widget in a modelForm that includes an ImageField in the model.

Particularly I don't want the Delete Checkbox that is part of the widget. I've tried customizing/overriding the rendering in a number of ways to get rid of the checkbox including setting the widget to FileInput and overriding the render method where subclassing the widget in a widgets.py file.

The simplest I can explain the problem is like this:

forms.py

class SpecImageForm(ModelForm):
  orig_image = forms.ImageField(required=False, widget=forms.FileInput)
  class Meta:
    model = SpecImage
    fields = ['orig_image',]


# The intention is to have more than one SpecImageForm once this is working but for now the 
# max_num is set to 1
SpecImageFormSet = inlineformset_factory(Spec, SpecImage, form=SpecImageForm, extra=1, max_num=1)

Despite explicitly setting the FileInput against the widget it renders like this in my template - still including the checkbox which I don't think should be present using FileInput.

<fieldset>
  <legend>Images</legend>
    <input id="id_specimage_set-TOTAL_FORMS" name="specimage_set-TOTAL_FORMS" type="hidden" value="1" />
    <input id="id_specimage_set-INITIAL_FORMS" name="specimage_set-INITIAL_FORMS" type="hidden" value="0" />   
    <input id="id_specimage_set-MAX_NUM_FORMS" name="specimage_set-MAX_NUM_FORMS" type="hidden" value="1" />    
      <ul>
        <li>
          <label for="id_specimage_set-0-orig_image">Orig image:</label> 
          <input id="id_specimage_set-0-orig_image" name="specimage_set-0-orig_image" type="file" />
        </li>
        <li>
          <label for="id_specimage_set-0-DELETE">Delete:</label> 
          <input id="id_specimage_set-0-DELETE" name="specimage_set-0-DELETE" type="checkbox" />
          <input id="id_specimage_set-0-id" name="specimage_set-0-id" type="hidden" />
          <input id="id_specimage_set-0-car" name="specimage_set-0-car" type="hidden" />
        </li>
      </ul>
</fieldset> 

The relevant part of the template is this:

<fieldset>
  <legend>Images</legend>
  {{ image_form.management_form }}
  {% for form in image_form %}
    <ul>
    {{ form.as_ul }}
    </ul>
  {% endfor %}
</fieldset>

The only thing slightly different that I'm doing is using an inlineformset_factory.

I've also tried to override the rendering of a widget using widgets.py but similarly seem unable to rid myself of the defualt settings - principally based on this thread.

Any ideas or solution to rid myself of the checkbox would be gratefully received!

Community
  • 1
  • 1
jayuu
  • 443
  • 1
  • 4
  • 17

1 Answers1

1

I think this is to do with the inlineformset_factory applying a default can_delete parameter set to true, which was present regardless of how I'd prepared the form to use with it. Simply passing can_delete=False got rid of the Delete checkbox.

SpecImageFormSet = inlineformset_factory(Spec, SpecImage, form=SpecImageForm, extra=1, max_num=1, can_delete=False)

In addition when I rendered the form on it's own (without using inlineformset_factory) there was no sign of a 'Delete checkbox'. Then I found this SO post that explained why.

Getting there.

Community
  • 1
  • 1
jayuu
  • 443
  • 1
  • 4
  • 17