如何在Django中使用csv.DictReader上传和读取csv文件?

15 投票
3 回答
28476 浏览
提问于 2025-04-18 12:59

我正在通过上传一个csv文件来读取数据,并想把所有的值存储到一个列表里。

def upload(request):
    paramFile = request.FILES['file'].read()
    data = csv.DictReader(paramFile)
    list1 = []
    for row in data:
        list1.append(row)

    print list1

file.csv

12345,abcdef

output

[{'1': '', None: ['']}, {'1': '2'}]

我想把所有的值添加到list1这个列表里。

3 个回答

17

在Python 3中,如果你想要正确的类型(字符串而不是字节),而又不想把整个文件都读到内存里,可以使用生成器逐行解码:

def decode_utf8(input_iterator):
    for l in input_iterator:
        yield l.decode('utf-8')

def upload(request):
    reader = csv.DictReader(decode_utf8(request.FILES['file']))
    for row in reader:
        print(row)
48

如果你在用Python 3,这个方法应该可以用。

file = request.FILES['file'] 
decoded_file = file.read().decode('utf-8').splitlines()
reader = csv.DictReader(decoded_file)
for row in reader:
    # Get each cell value based on key-value pair. 
    # Key will always be what lies on the first row.

我们可以使用splitlines()创建的列表。之所以用splitlines(),是因为csv.DictReader需要一个“任何支持迭代协议并且每次调用next()方法时返回一个字符串的对象——文件对象和列表对象都可以用”。

8

你遇到了两个问题:

  • 你把一个字符串传给了DictReader的构造函数。其实你应该传一个可以迭代的对象,这个对象能逐行提供输入内容(虽然字符串是可以迭代的,但它会一个字符一个字符地给你)。幸运的是,UploadedFile对象(比如在FILES字典里的那些)本身就是可以像文件一样迭代的对象,所以你只需要这样做:

    data = csv.DictReader(request.FILES['file'])
    
  • 你的输入数据只有一行。DictReader会把这一行当作“表头”,也就是结果字典里的键。这样的话,你就没有数据了!看起来你并不需要DictReader,而是一个普通的reader

    data = csv.reader(request.FILES['file'])
    

撰写回答