Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manually pass files to Django Form

I have a form:

class MessageAttachmentForm(forms.ModelForm):
    class Meta:
        model = MessageAttachment
        fields = ("attachment",)

And in my view, I have it receive some files with the incorrect names so I try to create a new MultiValueDict and submit the files one by one using the correct name like so:

if request.FILES:
    files_dict = request.FILES.copy()
    files_dict.clear()

    for file in request.FILES:
        files_dict["attachment"] = request.FILES.get(file)
        attachment_form = MessageAttachmentForm(files_dict)

        if attachment_form.is_valid():
            attachment = attachment_form.save()
            message_object.attachments.add(attachment)

Where origininally, the request.FILES returns this:

<MultiValueDict: {'attachment0': [<InMemoryUploadedFile: some_image.png (image/png)>], 'attachment1': [<InMemoryUploadedFile: report.pdf (application/pdf)>]}>

And on every iteration of request.FILES, when I add the file to the files_dict, I get this:

<MultiValueDict: {'attachment': [<InMemoryUploadedFile: some_image.png (image/png)>]}>

#And

<MultiValueDict: {'attachment': [<InMemoryUploadedFile: report.pdf (application/pdf)>]}>

Which looks ok, but still doesn't work. I also tried using a regular dict but that was to no avail either.
The attachment_form.errors says that the field attachment is required.

Thank you for taking your time reading this any help is appreciated.

like image 553
Unknown Username Avatar asked Jan 21 '26 09:01

Unknown Username


1 Answers

While creating a form instance you need to first pass the post data and then the files. They are positional named arguments:

class BaseModelForm(BaseForm):
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=ErrorList, label_suffix=None,
                 empty_permitted=False, instance=None, use_required_attribute=None,
                 renderer=None):
        ...

source: https://github.com/django/django/blob/master/django/forms/models.py#L280

You need to init your for as following:

        attachment_form = MessageAttachmentForm(files=files_dict)

or this way:

        attachment_form = MessageAttachmentForm(None, files_dict)
like image 54
scriptmonster Avatar answered Jan 23 '26 02:01

scriptmonster



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!