You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不保存读取上传CSV文件?解决bytes迭代错误

解决Django上传文件使用csv.reader时的字节模式报错问题

你直接将request.FILES["file"]传给csv.reader导致报错,核心原因是Django的TemporaryUploadedFile默认以二进制模式打开,而csv.reader需要返回字符串的文本模式迭代器。以下是两种可行的解决方法:

方法1:用io.TextIOWrapper包装文件对象

通过io.TextIOWrapper将二进制文件对象转换为文本模式,指定正确编码即可:

import io
import csv
from django import forms

class UploadForm(forms.Form):
    file = forms.FileField()

def import_file(request):
    if request.method != 'POST':
        form = UploadForm()
    else:
        form = UploadForm(request.POST, request.FILES)
        if form.is_valid():
            uploaded_file = request.FILES["file"]
            # 替换为实际文件编码,如utf-8、gbk等
            text_file = io.TextIOWrapper(uploaded_file.file, encoding='utf-8')
            rdr = csv.reader(text_file, delimiter=',')
            for row in rdr:
                print(row)
                # 你的业务逻辑处理
            text_file.close()
    # 后续响应逻辑
    return render(request, 'upload.html', {'form': form})

方法2:使用codecs.getreader创建文本迭代器

利用codecs模块的文本读取器,直接将二进制流转换为文本行迭代器:

import codecs
import csv
from django import forms

class UploadForm(forms.Form):
    file = forms.FileField()

def import_file(request):
    if request.method != 'POST':
        form = UploadForm()
    else:
        form = UploadForm(request.POST, request.FILES)
        if form.is_valid():
            uploaded_file = request.FILES["file"]
            # 创建指定编码的文本读取器
            text_reader = codecs.getreader('utf-8')(uploaded_file)
            rdr = csv.reader(text_reader, delimiter=',')
            for row in rdr:
                print(row)
                # 你的业务逻辑处理
    # 后续响应逻辑
    return render(request, 'upload.html', {'form': form})

关键说明

  • 必须根据上传CSV文件的实际编码设置encoding参数,编码错误会导致乱码。
  • 直接调用read()+decode()无法解决问题,因为csv.reader需要的是逐行迭代的文本对象,而非一次性读取的完整字符串。

内容的提问来源于stack exchange,提问作者Viktor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 16:24:56