6

I am trying to have a Django Model form with an image field but I have the two problems:

  1. I don't know how to show the current name of the image in the input
  2. I don't know how to provide a way to remove the image

forms:

class CityLogoForm(forms.ModelForm):
    logo = forms.ImageField(widget=forms.FileInput(attrs={'class': 'custom-file-input'}), required=False)

    class Meta:
        model = City
        fields = ['logo']

views:

def management_form_general(request, city_slug):
    city = City.objects.get(slug=city_slug)
    if request.method == 'POST':
        logo_form = CityLogoForm(request.POST, request.FILES,  instance=city)
        if logo_form.is_valid():
            logo_form.save()

    else:
        logo_form = CityLogoForm(instance=city)

    return render(request, 'management/form/city_general.html', {'city': city, 'logo_form': logo_form})

html:

<form action="" enctype="multipart/form-data" method="post">
    <div class="form-group row">
        <label for="id_city" class="col-sm-2 col-form-label form_title">{{ logo_form.logo.label }}</label>
        <div class="custom-file">
            {{ logo_form.logo }}
            <label class="custom-file-label" for="{{ logo_form.logo.id_for_label }}" data-browse="Choisir Image">{{ logo_form.logo.label }}</label>
        </div>
    </div>
</form>

I have a script changing the label when the user is uploading something but I cannot find a way to get the current value for the image fields (for the normal ones it's properly prepopulated). As it seems to not prepopulate the input, it seems to be ignoring when the input is empty and therefore never deletes the current logo.

Edit : if possible the answer need to be doable in a for loop over a formset_factory

BleuBizarre
  • 368
  • 2
  • 15
  • You can check what django-admin does. Take a look at the source code for the [widget html](https://github.com/django/django/blob/master/django/contrib/admin/templates/admin/widgets/clearable_file_input.html) & [widget form field code](https://github.com/django/django/blob/master/django/forms/widgets.py#L394) – shad0w_wa1k3r Nov 09 '19 at 21:58
  • try `{{ city.logo.url }}` in src of for showing – Yugandhar Chaudhari Nov 14 '19 at 08:35
  • Hey @YugandharChaudhari, thanks but how can i do when I am using formset_factory ? I won't have the model in my view when doing the foor loop. Was looking for a method that was working pretty much everytime but seems there is none – BleuBizarre Nov 14 '19 at 12:58

1 Answers1

2

I don't know how to show the current name of the image in the input

Add to you model a property that return image file name if image field is not blank, for example:

import os

class MyModel(models.Model):

    image = models.ImageField(...)

    @property
    def image_name(self):
        return os.path.basename(self.image.path) if self.image else ''

then in the html template add {{ your_model.image_name }} where you need to display the current image name.

I don't know how to provide a way to remove the image

I had the same problem recently and I solved it by adding an hidden checkbox clear_image in the html (checking it using js when user clicked clear image button), than I handled the received value in the django form.

Fabio Caccamo
  • 1,871
  • 19
  • 21
  • Thanks for this answer, for a formset you would load all the objects and pass it to the view ? – BleuBizarre Nov 13 '19 at 11:39
  • @BleuBizarre why all the objects? Just one object. – Fabio Caccamo Nov 13 '19 at 13:44
  • I might do everything wrong but when I am doing formset_factory (model or inline, whatever) in the template I am having multiple forms (with a for loop) without really knowing which object each are using – BleuBizarre Nov 13 '19 at 13:51