如何使用 Django 请求正确下载文件
How to correctly to download file with django requests
我是 运行 一个可以上传文件的 Django 应用程序。现在我想使用请求下载文件。我试图创建一个下载文件的视图,这样我就可以通过请求进行调用。但是不太行
My model:
class FileCollection(models.Model):
name = models.CharField(max_length=120, null=True, blank=True)
store_file = models.FileField(storage=PrivateMediaStorage(), null=True, blank=True)
creation_date = models.DateTimeField(null=True, blank=True)
My views
def fileview(request, *args, **kwargs):
file = FileCollection.objects.first()
file_path = file.store_file
print(file_path)
FilePointer = open(file_path, "r")
response = HttpResponse(FilePointer, content_type='application/msexcel')
response['Content-Disposition'] = 'attachment; filename=NameOfFile'
return response
它告诉我 TypeError: expected str, bytes or os.PathLike object, not FieldFile
如果我传入 apiview/admin 中提供的 url,我得到:FileNotFoundError: [Errno 2] No such file or directory
也尝试过:
def fileview(request):
path = FileCollection.objects.first()
obj = path.store_file
o = str(obj)
file_path = os.path.join(settings.MEDIA_ROOT, o)
print(file_path)
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(),
content_type="application/vnd.ms-excel")
response[
'Content-Disposition'] = 'inline; filename=' + os.path.basename(
file_path)
return response
但这给了我 ValueError: The view file_storage_api.api.v1.views.fileview didn't return an HttpResponse object. It returned None instead.
这是正确的方法吗?
非常感谢您的帮助或提示。
非常感谢
file_path = file.store_file
不是文件路径而是 FileField 的一个实例
尝试使用
file_path = file.store_file.name
并使用第二个片段
编辑:这是我使用的代码:
l_targetFile 是实际文件的路径
l_prjPath = os.path.realpath(os.path.dirname(__file__)).replace(<adapt the path here>)
l_userFileName= <file field>.name.replace('<upload to sub-dir>','')
l_targetFile = l_prjPath + '/media/' + l_fileObj.file_obj.name
#return the file
response = FileResponse(open(l_targetFile, 'rb'),\
(l_responseDisposition == 'attachment'))
#process the filename as stored on the local machine in case of download
try:
#check if it will throw
l_tmpUserName = l_userFileName.encode('ascii')
#no error use the non-encoded filename
l_fileExpr = 'filename="{0}"'.format(l_userFileName)
except UnicodeEncodeError:
# Handle a non-ASCII filename
l_fileExpr = "filename*=utf-8''{}".format(quote(l_userFileName))
response['Content-Disposition'] = '{0};{1};'.format(l_responseDisposition,l_fileExpr)
if '.pdf' in l_userFileName:
response['Content-Type'] = 'application/pdf'
elif l_dataSource == CMSArchiveEntry.SOURCE_TAG:
response['Content-Type'] = 'text/html; charset=utf-8'
return response
我是 运行 一个可以上传文件的 Django 应用程序。现在我想使用请求下载文件。我试图创建一个下载文件的视图,这样我就可以通过请求进行调用。但是不太行
My model:
class FileCollection(models.Model):
name = models.CharField(max_length=120, null=True, blank=True)
store_file = models.FileField(storage=PrivateMediaStorage(), null=True, blank=True)
creation_date = models.DateTimeField(null=True, blank=True)
My views
def fileview(request, *args, **kwargs):
file = FileCollection.objects.first()
file_path = file.store_file
print(file_path)
FilePointer = open(file_path, "r")
response = HttpResponse(FilePointer, content_type='application/msexcel')
response['Content-Disposition'] = 'attachment; filename=NameOfFile'
return response
它告诉我 TypeError: expected str, bytes or os.PathLike object, not FieldFile
如果我传入 apiview/admin 中提供的 url,我得到:FileNotFoundError: [Errno 2] No such file or directory
也尝试过:
def fileview(request):
path = FileCollection.objects.first()
obj = path.store_file
o = str(obj)
file_path = os.path.join(settings.MEDIA_ROOT, o)
print(file_path)
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(),
content_type="application/vnd.ms-excel")
response[
'Content-Disposition'] = 'inline; filename=' + os.path.basename(
file_path)
return response
但这给了我 ValueError: The view file_storage_api.api.v1.views.fileview didn't return an HttpResponse object. It returned None instead.
这是正确的方法吗?
非常感谢您的帮助或提示。 非常感谢
file_path = file.store_file
不是文件路径而是 FileField 的一个实例 尝试使用
file_path = file.store_file.name
并使用第二个片段
编辑:这是我使用的代码: l_targetFile 是实际文件的路径
l_prjPath = os.path.realpath(os.path.dirname(__file__)).replace(<adapt the path here>)
l_userFileName= <file field>.name.replace('<upload to sub-dir>','')
l_targetFile = l_prjPath + '/media/' + l_fileObj.file_obj.name
#return the file
response = FileResponse(open(l_targetFile, 'rb'),\
(l_responseDisposition == 'attachment'))
#process the filename as stored on the local machine in case of download
try:
#check if it will throw
l_tmpUserName = l_userFileName.encode('ascii')
#no error use the non-encoded filename
l_fileExpr = 'filename="{0}"'.format(l_userFileName)
except UnicodeEncodeError:
# Handle a non-ASCII filename
l_fileExpr = "filename*=utf-8''{}".format(quote(l_userFileName))
response['Content-Disposition'] = '{0};{1};'.format(l_responseDisposition,l_fileExpr)
if '.pdf' in l_userFileName:
response['Content-Type'] = 'application/pdf'
elif l_dataSource == CMSArchiveEntry.SOURCE_TAG:
response['Content-Type'] = 'text/html; charset=utf-8'
return response