Django unable to bind uploaded file

Viewed 40

Clarification: I'm developing on top of the django admin module.

I implemented a csv model upload using a simple FileField form, and read the uploaded text file with a TextIOWrapper without any problems.

I am trying to add an intermediate screen warning the user of potential data loss. I'm basing it off the admin delete action confirmation screen. The problem I'm having is passing the in-memory uploaded file to the intermediate screen to access it upon user confirmation. I tried doing this with a bound form but the uploaded data seems to vanish.

I am using a very simple form:

class CsvImportForm(forms.Form):
    csv_file = forms.FileField()
    overwrite = forms.BooleanField()

I have no problem when serving the GET view.

Now comes the funny part. When processing the same view for a POST request, I try to bind the form as per the documentation, and pass it to the template builder:

def import_csv(self, request, form_url="", extra_context=None):
    ...
    if request.method == "POST":
        form = CsvImportForm(request.POST, request.FILES)
        context.update({'form': form})
        ...
        return TemplateResponse(
            request,
            "admin/import_confirm.html",
            context
    )

The import_csv method is part of my ModelAdmin subclass, and gets called by overriding the get_urls method.

The template builds the form like so:

<form action="{{ form_url }}" method="post" enctype="multipart/form-data">{% csrf_token %}
    ...
    {{ form.csv_file }}
    ...
    <input type="submit" value="{% translate 'Yes, I’m sure' %}">
    <a href="#" class="button cancel-link">{% translate "No, take me back" %}</a>
    ...
</form>

However, when loading this view, the builtin ClearableFileInput appears empty. I even tried loading the same template as the GET view but the same problem appears. Of particular note, the BooleanField gets bound correctly if I choose to put it.

During debugging, the file does exist in request.FILES, but it somehow dissapears after passing the view to the renderer.

What am I overlooking? Or is there a better way to pass the file?

1 Answers

I discovered that for security reasons, it's not possible to serve the user a form with a bound file.

My solution was to use a javascript popup, so that way the content doesn't have to reload.

Related