8

I am trying to add an option to add multiple files at once in a form, and I found the solution with using ClearableFileInput:

class Image(models.Model):
    id = models.AutoField(primary_key=True)
    post = models.ForeignKey(BlogEntry, on_delete=models.CASCADE)
    photo = models.ImageField(null=True, blank=True, upload_to='media/')
    photo_objects = models.Manager()


class ImageForm(forms.ModelForm):
    class Meta:
        model = Image
        fields = ['photo', ]
        widgets = {

            'photo': forms.ClearableFileInput(attrs={'multiple': True})

        }

However, when I tried to run it using runserver, it gave me an error. Can somebody help me with fixing it? Is there another straightforward option to add multiple files?

I tried to search difference solutions on the internet but some of them did not work while others looked too complicated for my current level. I also see this option to upload multiple files in the official documentation (https://docs.djangoproject.com/en/dev/topics/http/file-uploads/) but I wonder if there is a simpler version in which I would not need to create MultipleFileInput and MultipleFileField by myself. Is there something in Django to enable multiple file upload?

1

3 Answers 3

16

I once experienced the same issue, came across many articles and answers on the net but all were suggesting to use
forms.ClearableFileInput(attrs={'multiple': True}) .
The only option that worked was the one provided in the official documentation (which you are finding hard to implement). For your case, your code in the file forms.py (the one which contains class ImageForm) will have to include this -

class MultipleFileInput(forms.ClearableFileInput):
    allow_multiple_selected = True

class MultipleFileField(forms.FileField):
    def __init__(self, *args, **kwargs):
        kwargs.setdefault("widget", MultipleFileInput())
        super().__init__(*args, **kwargs)

    def clean(self, data, initial=None):
        single_file_clean = super().clean
        if isinstance(data, (list, tuple)):
            result = [single_file_clean(d, initial) for d in data]
        else:
            result = single_file_clean(data, initial)
        return result

class ImageForm(forms.ModelForm):
    photo = MultipleFileField(label='Select files', required=False)

    class Meta:
        model = Image
        fields = ['photo', ]

Remember that you'll have to update your function accepting the request/files in the views.py accordingly. For example -

def function(request):
    if request.method == 'POST' :
        uploaded_images = request.FILES.getlist('photo')
        for image in uploaded_images:
            #your task here (What you want to do with the image)

Let me know if this works!

Sign up to request clarification or add additional context in comments.

1 Comment

It works for me. I have recently upgraded Django from 3.2 to 4.2 and started having this issue. Now, it has solved this issue with Django 4.2.
5

You can change:

class ImageForm(forms.ModelForm):
    class Meta:
        model = Image
        fields = ['photo', ]
        widgets = {
            'photo': forms.ClearableFileInput(attrs={'multiple': True})
        }

to:

class ImageForm(forms.ModelForm):
    class Meta:
        model = Image
        fields = ['photo', ]
        widgets = {

            'photo': forms.ClearableFileInput(attrs={'allow_multiple_selected': True})

        }

1 Comment

ValueError: ClearableFileInput doesn't support uploading multiple files.
2

Why This Issue Occurs: The error ValueError: ClearableFileInput doesn't support uploading multiple files indicates that this functionality is not supported in Django 5. However, it works in Django 4.0.6, as confirmed through testing.

Fix for This Issue: You can resolve the issue by customizing the widget behavior of the specific field. Here's how to modify the widget to allow multiple file uploads:

class ImageForm(forms.ModelForm):
    class Meta:
        model = Image
        fields = ['photo', ]
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Add the `multiple` attribute to allow selecting multiple files
        self.fields["photo"].widget.attrs.update({"multiple": "true"})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.