如何正确将CSV文件上传至Django模型?解决InMemoryUploadedFile报错
问题描述
尝试将CSV文件上传至Django模型,编写的实现代码如下:
def post(self, request): if(request.method=='POST'): # csv_file=request.FILES.get('file') csv_file = request.FILES['file'] with open(csv_file, 'r') as csvfile: # reader=csv_file.read().decode("utf-8") # reader=TimeSeries.import_data(data = open(csv_file)) # reader = csv.reader(csv_file.read().decode('utf-8').splitlines()) reader = csv.reader(csvfile) print("here3") print (reader); for row in reader: print("here4") print(row) queryset = Station.objects.all() print("here5") # serializer_class = TimeSeriesSerializer queryset = queryset.filter(name=row['Station Name']) TimeSeriesInstance=TimeSeries(station=queryset.number,date=row['Date'],hour=row['Time'],value=row['Value']) TimeSeriesInstance.save() # process_file.delay(csv_file) return HttpResponse('Success')
尝试过修改注释掉的代码测试,但始终出现不同错误,当前触发的错误为:
expected str, bytes or os.PathLike object, not InMemoryUploadedFile
问题原因与解决方法
1. 核心错误原因
open()函数要求传入文件路径字符串,但你传入的csv_file是Django的InMemoryUploadedFile对象——这本身就是一个类文件对象,支持直接读取,不需要再用open()二次打开。
2. 修正后的代码示例
import csv from django.http import HttpResponse def post(self, request): if request.method == 'POST': csv_file = request.FILES['file'] # 直接读取上传文件内容,用DictReader通过列名访问数据(前提是CSV首行为表头) reader = csv.DictReader(csv_file.read().decode('utf-8').splitlines()) for row in reader: # filter返回QuerySet集合,需用get()/first()获取单个对象,同时处理不存在的情况 try: station = Station.objects.get(name=row['Station Name']) TimeSeries.objects.create( station=station, date=row['Date'], hour=row['Time'], value=row['Value'] ) except Station.DoesNotExist: # 可根据需求跳过该行或记录错误日志 continue return HttpResponse('Success')
3. 其他需注意的问题
- CSV读取方式:如果CSV首行是表头,
csv.DictReader比csv.reader更易用——后者返回列表,只能通过索引(如row[0])取值,无法直接用列名。 - QuerySet处理:
filter()返回的是对象集合,不能直接访问number属性,必须用get()获取唯一匹配对象,或first()取第一个匹配对象,同时要捕获Station.DoesNotExist异常避免报错。 - 编码适配:若CSV文件不是UTF-8编码,需调整
decode()参数,比如decode('gbk')。
内容的提问来源于stack exchange,提问作者Muhammad Waqar Anwar
相关产品推荐
相关产品推荐

