5

I'm attempting to process an uploaded CSV file using Django. The main logic of how I go about doing this is expressed in both the models.py and views.py scripts. Once I've uploaded the file, I'm unable to process any of the content (in my views.py). Here are the two scripts, but if there's any more information I can provide, I'd be happy to.

In my models.py file, I have two classes, one for the document itself, and the other class for the fields in the file.

models.py:

from django.db import models

import os

class Document(models.Model):
    docfile = models.FileField(upload_to='documents')

class DocumentEntry(models.Model):
    document = models.ForeignKey(Document, on_delete=models.CASCADE)
    field = models.CharField(max_length=250, default="TEST")

Next, in my views.py I get the file that was uploaded via the request.FILES['docfile'] and pass it to the handle_files() function. However, when I try to loop through the reader, I'm unable to access any of the elements in the file that was uploaded.

views.py:

from django.shortcuts import render
from django.conf import settings
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse

import csv

from .models import Document, DocumentEntry
from .forms import UploadFileForm


def process_file(request):
    # Handle file upload
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():

            handle_files(request.FILES['docfile'])

            # Redirect to the document list after POST
            return HttpResponseRedirect(reverse('process_files'))
    else:
        form = UploadFileForm()  # A empty, unbound form

    # Load documents for the list page
    documents = Document.objects.all()

    # Render list page with the documents and the form
    return render(
        request,
        'upload/process_files.html',
        {'documents': documents, 'form': form}
    )


def handle_files(csv_file):

    newdoc = Document(docfile=csv_file)
    newdoc.save()

    reader = csv.DictReader(open(csv_file))
    for row in reader:
        field = row['field']
        entry = DocumentEntry(document=newdoc, field=field)
        entry.save()

2 Answers 2

4

Updated

Here is full example of handler function:

def handle_files(csv_file):

   newdoc = Document(docfile=csv_file)
   newdoc.save()

   with open(newdoc.docfile.name) as f:
      reader = csv.DictReader(f)
      for row in reader:
         field = row['field']
         entry = DocumentEntry(document=newdoc, field=field)
         entry.save()
Sign up to request clarification or add additional context in comments.

7 Comments

Any ideas on how I would get the name? I can create a helper function in models.py to return the filename, but of course, I wouldn't be able to access that function when creating an object.
I have updated my answer for example of file name function. Seems we also need to use read() from file object.
Here is what information you can get from uploaded file: file = request.FILES['filename'] file.name # Gives name file.content_type # Gives Content type text/html etc file.size # Gives file's size in byte file.read() # Reads file
Thanks Gagik, what is File in your example where newdoc = Document(docfile=File(csv_file.read(), name=csc_file.name))
Oh sorry, I had to point it. It is: from django.core.files.base import File
|
1

open() expects the path to the file, not the actual file data, which is contained in request.FILES['docfile'].

Replace:

reader = csv.DictReader(open(csv_file))

with:

import io
io_file = io.TextIOWrapper(csv_file.file)
reader = csv.DictReader(io_file)

7 Comments

Thanks Lucas, although this appears to give me the following error: iterator should return strings, not bytes (did you open the file in text mode?)
@VincentRusso True, updated my answer with the proper fix.
thanks again, but it seems that now the program does not enter the for row in reader: loop. Indeed, when I check print(list(reader)), the list is empty. Any thoughts?
Check if csv_file.file is empty too. That would be very odd.
Yeah it is, and I have no idea why that would be the case. It may be because I'm passing the request.FILES['docfile'] to the handle_files(csv_file) function. It seems when I just try to do what you suggested directly after if form.is_valid(), I get the error: 'charmap' codec can't encode character '\u20ac' in position 12588: character maps to <undefined>
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.