【问题标题】:How to correctly to download file with django requests如何使用 django 请求正确下载文件
【发布时间】:2020-02-18 15:36:49
【问题描述】:

我正在运行一个可以上传文件的 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.

这是正确的方法吗?

非常感谢您的帮助或提示。 非常感谢

【问题讨论】:

    标签: django django-rest-framework django-views django-file-upload


    【解决方案1】:
    file_path = file.store_file
    

    不是文件路径,而是 FileField 的一个实例 尝试使用

    file_path = file.store_file.name
    

    并使用第二个 sn-p

    编辑:这是我使用的代码: 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
    

    【讨论】:

    • 谢谢我的朋友!当我尝试这个时,即使文件在那里,我仍然会得到File not found error。它在 AWS 存储桶中,但 django 仍然应该找到它吗?
    • 我做到了:file_path = file.store_file read_file = file_path.read()
    • AWS 应该不会改变任何东西,但配置显然存在一些问题。 .name 应该返回一个相对于媒体根目录的路径。我将在下面添加用于呈现文件响应的代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 2021-03-16
    • 2021-08-06
    • 2014-01-16
    相关资源
    最近更新 更多