mjumbewu / django-rest-framework-csv

CSV Tools for Django REST Framework
BSD 2-Clause "Simplified" License
364 stars 89 forks source link

CSV Post generates error #30

Open johnecon opened 9 years ago

johnecon commented 9 years ago

I run this through a terminal:

curl -X POST -d @C://Users/johnecon/Downloads/participants.csv -H "Authorization: Token b6b904232cb4abb86ba3e01e299110df9d4c83a4" -H "Content-Type: text/csv" localhost:8000/api/config

This is my view in listening in api/config

from rest_framework.decorators import api_view, authentication_classes, parser_classes
from rest_framework_csv import parsers as p
@api_view(['POST'])
@authentication_classes((authentication.BasicAuthentication, authentication.TokenAuthentication))
@parser_classes([p.CSVParser])
def CsvConfig(request):
    f = request.FILES
    return Response({"success": True})

The error I am getting:

{"detail":"CSV parse error - iterator should return strings, not bytes (did you open the file in text mode?)"}

I am using python 3.4.2 django 1.7

This is how my csv looks when I edit it:

First Name|Last Name|Username|Project|SubProject|Role|Phone|Skype
Andreas Kær,Eriksen,s133998,02264F15,1A,Leader,,skype_1
Ernst Magnus,Nylander,s122176,02264F15,1A,Contibutor,,skype_2
Mike Østergaard,Behrens,s133987,02264F15,1B,Leader,,skype_28

Any help would be highly appreciated :)

munendrasn commented 9 years ago

@johnecon This might help you. If you find any better answer please share it. http://stackoverflow.com/questions/22132034/ http://stackoverflow.com/questions/8515053/

mjumbewu commented 9 years ago

@johnecon Interesting. What version of django-rest-framework-csv are you using? I though this should have been fixed since v1.3.3 (but maybe not?).

johnecon commented 9 years ago

That was on django-rest-framework-csv v1.3.3 I ended up using the following

@api_view(['POST'])
@authentication_classes((authentication.BasicAuthentication, authentication.TokenAuthentication))
@transaction.atomic
def csv_config(request):
    headers = None
    content = {}
    f = TextIOWrapper(request.FILES['config'].file, encoding='utf-8')
    reader = csv.reader(f.read().splitlines())
MasterKale commented 9 years ago

I'm having the same issue, though instead of uploading a file I'm POSTing the contents of the file with Content-Type set to text/csv. The request makes it to the server, but I get back a 400 (BAD REQUEST) with the error message that johnecon originally posted.

Here's the AngularJS method that makes the request:

service.bulkUploadEmployees = function(csvData) {
    return $http.post(SERVER_URL + 'v1/admin_site/bulk_upload_employees/', csvData, {
        headers: { 'Content-Type': 'text/csv' }
    });
};

And it's just a placeholder for now but here's the view that handles things on the server:

class BulkCreateEmployeesView(CreateAPIView):
    parser_classes = [CSVParser]

    def create(self, request, *args, **kwargs):
        return Response(request.data)

The View handles things fine if I don't set a Content-Type from the request and omit parser_classes from the View; basically, it works when I don't use django-rest-framework-csv. However I'd still like to keep things as best-practices as possible and encourage future-Me to set the proper Content-Type when I make this request.

rikkiprince commented 8 years ago

I'm not sure if this is related, but I'm getting:

Invalid data. Expected a dictionary, but got OrderedRows.

when I try to post CSV data at my create view. The CSV data is basically a reflection of what I get back from the CSV renderer:

authors.0,authors.1,authors.2,date_published,isbn13,owner,pages,publisher,title,url
http://waisvm-rfp1.ecs.soton.ac.uk/authors/1,http://waisvm-rfp1.ecs.soton.ac.uk/authors/2,http://waisvm-rfp1.ecs.soton.ac.uk/authors/3,2010-09-01,9781234567890,rfp1n11,1024,http://waisvm-rfp1.ecs.soton.ac.uk/publishers/1,Testing Text CSV,http://waisvm-rfp1.ecs.soton.ac.uk/books/1

I'm not really sure what's causing it. Does anyone have any clue what the problem could be?

I'm using djangorestframework-csv==1.3.4.

Symmetric commented 8 years ago

I've hit this too -- applying this change (https://github.com/mjumbewu/django-rest-framework-csv/pull/47) seems to have resolved the issue.

Can anyone else seeing the above problem clarify whether they were using Python3 or Python2? The fix I made is just for Python3.

cjsmith commented 3 years ago

For what it's worth 5 years later @rikkiprince and others who run into this issue in the future, I ran into the "Expected a dictionary, but got OrderedRows" issue with a POST request (although I think file upload would have also triggered it). It was being thrown by my serializer because I hadn't passed many=True argument to the serializer constructor, so it was trying to serialize all the rows of the CSV instead of an individual row at a time.