django通过HttpResponse返回文件 - 文件未正确提供

时间:2021-09-18 20:23:31

I want to return some files in a HttpResponse and I'm using the following function. The file that is returned always has a filesize of 1kb and I do not know why. I can open the file, but it seems that it is not served correctly. Thus I wanted to know how one can return files with django/python over a HttpResponse.

我想在HttpResponse中返回一些文件,我正在使用以下函数。返回的文件总是有1kb的文件大小,我不知道为什么。我可以打开文件,但似乎没有正确提供。因此,我想知道如何通过HttpResponse使用django / python返回文件。

@login_required
def serve_upload_files(request, file_url):
    import os.path
    import mimetypes
    mimetypes.init()

    try:
        file_path = settings.UPLOAD_LOCATION + '/' + file_url
        fsock = open(file_path,"r")
        #file = fsock.read()
        #fsock = open(file_path,"r").read()
        file_name = os.path.basename(file_path)
        file_size = os.path.getsize(file_path)
        print "file size is: " + str(file_size)
        mime_type_guess = mimetypes.guess_type(file_name)
        if mime_type_guess is not None:
            response = HttpResponse(fsock, mimetype=mime_type_guess[0])
        response['Content-Disposition'] = 'attachment; filename=' + file_name            
    except IOError:
        response = HttpResponseNotFound()
    return response

Edit: The bug is actually not a bug ;-)

编辑:这个bug实际上不是一个bug ;-)

This solution is working in production on an apache server, thus the source is ok.

此解决方案正在apache服务器上进行生产,因此源可以。

While writing this question I tested it local with the django development server and was wondering why it does not work. A friend of mine told me that this issue could arise if the mime types are not set in the server. But he was not sure if this is the problem. But one thing for sure.. it has something to do with the server.

在写这个问题时,我用django开发服务器在本地测试它,并想知道为什么它不起作用。我的一位朋友告诉我,如果未在服务器中设置mime类型,则可能会出现此问题。但他不确定这是不是问题。但有一件事是肯定的......它与服务器有关。

3 个解决方案

#1


9  

Try passing the fsock iterator as a parameter to HttpResponse(), rather than to its write() method which I think expects a string.

尝试将fsock迭代器作为参数传递给HttpResponse(),而不是传递给我认为需要字符串的write()方法。

response = HttpResponse(fsock, mimetype=...)

See http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators

见http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators

Also, I'm not sure you want to call close on your file before returning response. Having played around with this in the shell (I've not tried this in an actual Django view), it seems that the response doesn't access the file until the response itself is read. Trying to read a HttpResponse created using a file that is now closed results in a ValueError: I/O operation on closed file.

另外,我不确定你想在返回响应之前调用你的文件。在shell中玩过这个(我没有在实际的Django视图中尝试过这个),似乎响应在读取响应本身之前不会访问文件。尝试读取使用现在关闭的文件创建的HttpResponse会导致ValueError:关闭文件上的I / O操作。

So, you might want to leave fsock open, and let the garbage collector deal with it after the response is read.

因此,您可能希望保持fsock处于打开状态,并在读取响应后让垃圾收集器处理它。

#2


11  

Could it be that the file contains some non-ascii characters that render ok in production but not in development?

难道该文件包含一些非ascii字符,这些字符可以在生产中呈现,但不在开发中吗?

Try reading the file as binary:

尝试将文件读取为二进制文件:

fsock = open(file_path,"rb")

#3


1  

Try disabling "django.middleware.gzip.GZipMiddleware" from your MIDDLEWARE_CLASSES in settings.py

尝试从settings.py中的MIDDLEWARE_CLASSES禁用“django.middleware.gzip.GZipMiddleware”

I had the same problem, and after I looked around the middleware folder, this middleware seemed guilty to me and removing it did the trick for me.

我有同样的问题,在我浏览中间件文件夹后,这个中间件对我来说似乎有罪并且删除它对我来说很有用。

#1


9  

Try passing the fsock iterator as a parameter to HttpResponse(), rather than to its write() method which I think expects a string.

尝试将fsock迭代器作为参数传递给HttpResponse(),而不是传递给我认为需要字符串的write()方法。

response = HttpResponse(fsock, mimetype=...)

See http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators

见http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators

Also, I'm not sure you want to call close on your file before returning response. Having played around with this in the shell (I've not tried this in an actual Django view), it seems that the response doesn't access the file until the response itself is read. Trying to read a HttpResponse created using a file that is now closed results in a ValueError: I/O operation on closed file.

另外,我不确定你想在返回响应之前调用你的文件。在shell中玩过这个(我没有在实际的Django视图中尝试过这个),似乎响应在读取响应本身之前不会访问文件。尝试读取使用现在关闭的文件创建的HttpResponse会导致ValueError:关闭文件上的I / O操作。

So, you might want to leave fsock open, and let the garbage collector deal with it after the response is read.

因此,您可能希望保持fsock处于打开状态,并在读取响应后让垃圾收集器处理它。

#2


11  

Could it be that the file contains some non-ascii characters that render ok in production but not in development?

难道该文件包含一些非ascii字符,这些字符可以在生产中呈现,但不在开发中吗?

Try reading the file as binary:

尝试将文件读取为二进制文件:

fsock = open(file_path,"rb")

#3


1  

Try disabling "django.middleware.gzip.GZipMiddleware" from your MIDDLEWARE_CLASSES in settings.py

尝试从settings.py中的MIDDLEWARE_CLASSES禁用“django.middleware.gzip.GZipMiddleware”

I had the same problem, and after I looked around the middleware folder, this middleware seemed guilty to me and removing it did the trick for me.

我有同样的问题,在我浏览中间件文件夹后,这个中间件对我来说似乎有罪并且删除它对我来说很有用。