Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django upload and process file with no data retention

Python: 2.7.11

Django: 1.9

I want to upload a csv file to Django and analyze it with a Python class. No saving is allowed and the file is only needed to reach the class to be analyzed. I'm using Dropzone.js for the form but I don't understand how I should configure/program the views to achieve this.

<form action="/upload/" method="post" enctype="multipart/form-data" class="dropzone" id="dropzone">
    {% csrf_token %}
    <div class="fallback">
        <input name="file" type="file" multiple />
    </div>
</form>

I have found an article about this but it describes saving and is based on Django 1.5.

view.py

def upload(request):
    if request.method == 'POST':
        file = FileUploadForm(request.POST)
        if file.is_valid():
            return HttpResponseRedirect('/upload/')
    else:
        file = FileUploadForm()

    return render(request, 'app/upload.html', {'file': file})

forms.py

from django import forms
class FileUploadForm(forms.Form):
    file = forms.FileField()

Closing Update: The most important difference between the helping answer and my situation is that I had to decode my input. See the following line as mine csv_file in handle_csv_data:

StringIO(content.read().decode('utf-8-sig'))
like image 456
Adrian Z. Avatar asked Dec 04 '25 15:12

Adrian Z.


1 Answers

Access the csv file in the view function. If you are using python 3, you must wrap the InMemoryUploadedFile in a TextIOWrapper to parse it with the csv module.

In this example the csv is parsed and passed back as a list named 'content' that will be displayed as a table.

views.py

import csv
import io  # python 3 only

def handle_csv_data(csv_file):
    csv_file = io.TextIOWrapper(csv_file)  # python 3 only
    dialect = csv.Sniffer().sniff(csv_file.read(1024), delimiters=";,")
    csv_file.seek(0)
    reader = csv.reader(csv_file, dialect)
    return list(reader)


def upload_csv(request):
    csv_content=[]
    if request.method == 'POST':
        csv_file = request.FILES['file'].file
        csv_content = handle_csv_data(csv_file)  
    return render(request, 'upload.html', {'content':content})

Your original code did not use django's form framework correctly, so I just dropped that from this example. So you should implement error handling when the uploaded file is invalid or missing.

upload.html

  <form action="/upload/" 
        method="post" 
        enctype="multipart/form-data" 
        class="dropzone" 
        id="dropzone">
    {% csrf_token %}
    <div class="fallback">
      <input name="file" type="file"/>
      <input type="submit"/>
    </div>
  </form>
  {% if content %}
  <table>
  {% for row in content %}
    <tr>
    {% for col in row %}
      <td>{{ col }}</td>
    {% endfor %}
    </tr>
  {% endfor %}
  </table>
  {% endif %}

I've added a 'submit' button so this works without the dropzone thing. I also removed 'multiple' from the file input, to keep the example simple. Finally there's a table if the template receives content from a parsed csv. But when using dropzone.js, you have to use a javascript callback function to display the table.

like image 71
Håken Lid Avatar answered Dec 06 '25 05:12

Håken Lid



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!