{"id":3925,"date":"2018-05-12T18:13:08","date_gmt":"2018-05-12T10:13:08","guid":{"rendered":"https:\/\/ixyzero.com\/blog\/?p=3925"},"modified":"2018-05-12T18:13:08","modified_gmt":"2018-05-12T10:13:08","slug":"django%e4%b8%ad%e5%a6%82%e4%bd%95%e5%ae%9e%e7%8e%b0%e6%96%87%e4%bb%b6%e4%b8%8b%e8%bd%bd%e5%8a%9f%e8%83%bd","status":"publish","type":"post","link":"https:\/\/ixyzero.com\/blog\/archives\/3925.html","title":{"rendered":"Django\u4e2d\u5982\u4f55\u5b9e\u73b0\u6587\u4ef6\u4e0b\u8f7d\u529f\u80fd"},"content":{"rendered":"<p>=Start=<\/p>\n<h4 id=\"id-\u6a21\u677f-\u7f18\u7531\uff1a\">\u7f18\u7531\uff1a<\/h4>\n<p>\u5b66\u4e60\u3001\u6574\u7406\u4e00\u4e0b\u6700\u8fd1\u770b\u5230\u7684\u77e5\u8bc6\u70b9\uff0c\u65b9\u4fbf\u4ee5\u540e\u53c2\u8003\u3002<\/p>\n<h4 id=\"id-\u6a21\u677f-\u6b63\u6587\uff1a\">\u6b63\u6587\uff1a<\/h4>\n<h5 id=\"id-\u6a21\u677f-\u53c2\u8003\u89e3\u7b54\uff1a\">\u53c2\u8003\u89e3\u7b54\uff1a<\/h5>\n<h6><strong>\u65b9\u6cd5\u4e00\uff08\u76f4\u63a5<span style=\"color: #ff0000;\">HttpResponse<\/span>\u8fd4\u56de\u6587\u4ef6\u5185\u5bb9\uff09\uff1a<\/strong><\/h6>\n<pre class=\"lang:default decode:true\"># \u7b80\u5355\u7c97\u66b4\uff0c\u9002\u5408\u5c0f\u6587\u4ef6\u7684\u4e0b\u8f7d\r\ndef simple_file_download(request):\r\n    with open('manage.py') as f:\r\n        c = f.read()\r\n    return HttpResponse(c)<\/pre>\n<p>&amp;<\/p>\n<pre class=\"lang:default decode:true\"># \u501f\u52a9 FileWrapper \u5c06\u6587\u4ef6\u5bf9\u8c61\u5305\u88c5\u6210\u4e00\u4e2a\u8fed\u4ee3\u5668\r\ndef filewrapper_download(request):\r\n    the_file_name = \"manage.py\"\r\n\r\n    wrapper = FileWrapper(file(the_file_name))\r\n    response = HttpResponse(wrapper)\r\n    response['Content-Type'] = 'application\/octet-stream'\r\n    response['Content-Disposition'] = 'attachment;filename=\"{0}\"'.format(the_file_name)\r\n    return response<\/pre>\n<h6><strong>\u65b9\u6cd5\u4e8c\uff08\u4f7f\u7528<span style=\"color: #ff0000;\">StreamingHttpResponse<\/span>\u8fd4\u56de\u6587\u4ef6\u5185\u5bb9\uff09\uff1a<\/strong><\/h6>\n<pre class=\"lang:default decode:true\">def big_file_download(request):\r\n    def file_iterator(file_name, chunk_size=512):\r\n        with open(file_name) as f:\r\n            while True:\r\n                c = f.read(chunk_size)\r\n                if c:\r\n                    yield c\r\n                else:\r\n                    break\r\n\r\n    the_file_name = \"manage.py\"\r\n    response = StreamingHttpResponse(file_iterator(the_file_name))\r\n    return response<\/pre>\n<h6><strong>\u65b9\u6cd5\u4e09\uff08\u4f7f\u7528<span style=\"color: #ff0000;\">FileResponse<\/span>\u8fd4\u56de\u6587\u4ef6\u5185\u5bb9\uff09\uff1a<\/strong><\/h6>\n<pre class=\"lang:default decode:true\">def fileresponse_download(request):\r\n    the_file_name = \"manage.py\"\r\n\r\n    response = FileResponse(file(the_file_name))\r\n    return response\r\n<\/pre>\n<h6><strong>\u65b9\u6cd5\u56db\uff08\u6dfb\u52a0\u4e0a\u300c<span style=\"color: #ff0000;\">Content-Type<\/span>\u300d\u548c\u300c<span style=\"color: #ff0000;\">Content-Disposition<\/span>\u300dheader\u5b57\u6bb5\uff09\uff1a<\/strong><\/h6>\n<pre class=\"lang:default decode:true\">def fileresponse_download(request):\r\n    the_file_name = \"manage.py\"\r\n\r\n    response = FileResponse(file(the_file_name))\r\n    response['Content-Type'] = 'application\/octet-stream'\r\n    response['Content-Disposition'] = 'attachment;filename=\"{0}\"'.format(the_file_name)\r\n    return response\r\n<\/pre>\n<h6><strong>\u65b9\u6cd5\u4e94\uff08\u5148\u8ba9Django\u505a\u6743\u9650\u5224\u65ad\uff0c\u7136\u540e\u8ba9\u9759\u6001\u670d\u52a1\u5668\u5904\u7406\u4e0b\u8f7d\uff09\uff1a<\/strong><\/h6>\n<p>\u4e0d\u7ba1\u600e\u4e48\u6837\uff0c\u4f7f\u7528Django\u6765\u5904\u7406\u5927\u6587\u4ef6\u4e0b\u8f7d\u90fd\u4e0d\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u6ce8\u610f\uff0c\u6700\u597d\u7684\u529e\u6cd5\u662fDjango\u505a\u6743\u9650\u5224\u65ad\uff0c\u7136\u540e\u8ba9\u9759\u6001\u670d\u52a1\u5668\u5904\u7406\u4e0b\u8f7d\u3002<\/p>\n<p>\u8fd9\u9700\u8981\u4f7f\u7528sendfile\u7684\u673a\u5236\uff1a\u201c\u4f20\u7edf\u7684Web\u670d\u52a1\u5668\u5728\u5904\u7406\u6587\u4ef6\u4e0b\u8f7d\u7684\u65f6\u5019\uff0c\u603b\u662f\u5148\u8bfb\u5165\u6587\u4ef6\u5185\u5bb9\u5230\u5e94\u7528\u7a0b\u5e8f\u5185\u5b58\uff0c\u7136\u540e\u518d\u628a\u5185\u5b58\u5f53\u4e2d\u7684\u5185\u5bb9\u53d1\u9001\u7ed9\u5ba2\u6237\u7aef\u6d4f\u89c8\u5668\u3002\u8fd9\u79cd\u65b9\u5f0f\u5728\u5e94\u4ed8\u5f53\u4eca\u5927\u8d1f\u8f7d\u7f51\u7ad9\u4f1a\u6d88\u8017\u66f4\u591a\u7684\u670d\u52a1\u5668\u8d44\u6e90\u3002sendfile\u662f\u73b0\u4ee3\u64cd\u4f5c\u7cfb\u7edf\u652f\u6301\u7684\u4e00\u79cd\u9ad8\u6027\u80fd\u7f51\u7edcIO\u65b9\u5f0f\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5185\u6838\u7684sendfile\u8c03\u7528\u53ef\u4ee5\u5c06\u6587\u4ef6\u5185\u5bb9\u76f4\u63a5\u63a8\u9001\u5230\u7f51\u5361\u7684buffer\u5f53\u4e2d\uff0c\u4ece\u800c\u907f\u514d\u4e86Web\u670d\u52a1\u5668\u8bfb\u5199\u6587\u4ef6\u7684\u5f00\u9500\uff0c\u5b9e\u73b0\u4e86\u201c\u96f6\u62f7\u8d1d\u201d\u6a21\u5f0f\u3002\u201d<\/p>\n<p>Apache\u670d\u52a1\u5668\u91cc\u9700\u8981mod_xsendfile\u6a21\u5757\u6765\u5b9e\u73b0\uff0c\u800cNginx\u662f\u901a\u8fc7\u79f0\u4e3a<a href=\"https:\/\/www.nginx.com\/resources\/wiki\/start\/topics\/examples\/x-accel\/\" target=\"_blank\" rel=\"noopener\">X-Accel-Redirect<\/a>\u7684\u7279\u6027\u6765\u5b9e\u73b0\u3002<\/p>\n<p>nginx\u914d\u7f6e\u6587\u4ef6\uff1a<\/p>\n<pre class=\"lang:default decode:true\"># Will serve \/var\/www\/files\/myfile.tar.gz\r\n# When passed URI \/protected_files\/myfile.tar.gz\r\nlocation \/protected_files {\r\n    internal;\r\n    alias \/var\/www\/files;\r\n}\r\n\r\n# \u6216\u8005\r\n\r\n# Will serve \/var\/www\/protected_files\/myfile.tar.gz\r\n# When passed URI \/protected_files\/myfile.tar.gz\r\nlocation \/protected_files {\r\n    internal;\r\n    root \/var\/www;\r\n}\r\n\r\n# \u6ce8\u610falias\u548croot\u7684\u533a\u522b\u3002<\/pre>\n<p>Django\u4e2d\uff1a<\/p>\n<pre class=\"lang:default decode:true \">response['X-Accel-Redirect'] = '\/protected_files\/%s' % filename<\/pre>\n<p>\u8fd9\u6837\u5f53\u5411Django view\u51fd\u6570\u53d1\u8d77request\u65f6\uff0cDjango\u8d1f\u8d23\u5bf9\u7528\u6237\u6743\u9650\u8fdb\u884c\u5224\u65ad\u6216\u8005\u505a\u4e9b\u5176\u5b83\u4e8b\u60c5\uff0c\u7136\u540e\u5411nginx\u8f6c\u53d1url\u4e3a\/protected_files\/filename\u7684\u8bf7\u6c42\uff0cnginx\u670d\u52a1\u5668\u8d1f\u8d23\u6587\u4ef6\/var\/www\/protected_files\/filename\u7684\u4e0b\u8f7d\uff1a<\/p>\n<pre class=\"lang:default decode:true \">@login_required\r\ndef document_view(request, document_id):\r\n    book = Book.objects.get(id=document_id)\r\n    response = HttpResponse()\r\n    name=book.myBook.name.split('\/')[-1]\r\n    response['Content-Type']='application\/octet-stream'\r\n    response[\"Content-Disposition\"] = \"attachment; filename={0}\".format(\r\n            name.encode('utf-8'))\r\n    response['Content-Length'] = os.path.getsize(book.myBook.path)\r\n    response['X-Accel-Redirect'] = \"\/protected_files\/{0}\".format(book.myBook.name)\r\n    return response\r\n<\/pre>\n<p>*\u300c\u65b9\u6cd5\u4e94\u300d\u6682\u672a\u5b9e\u9645\u6d4b\u8bd5*\uff0c\u5148\u8bb0\u5f55\u81f3\u6b64\u4f9b\u53c2\u8003\u3002<\/p>\n<p>&nbsp;<\/p>\n<h5 id=\"id-\u6a21\u677f-\u53c2\u8003\u94fe\u63a5\uff1a\">\u53c2\u8003\u94fe\u63a5\uff1a<\/h5>\n<ul>\n<li><a href=\"https:\/\/blog.igevin.info\/post\/11\/\">Django \u5b9e\u73b0\u4e0b\u8f7d\u6587\u4ef6\u529f\u80fd<\/a><br \/>\n<a href=\"https:\/\/www.jianshu.com\/p\/2ce715671340\">https:\/\/www.jianshu.com\/p\/2ce715671340<\/a><\/li>\n<li><a href=\"https:\/\/www.cnblogs.com\/linxiyue\/p\/4187484.html\">Django \u5927\u6587\u4ef6\u4e0b\u8f7d<\/a><\/li>\n<li><a href=\"https:\/\/stackoverflow.com\/questions\/908258\/generating-file-to-download-with-django\">Generating file to download with Django<\/a><\/li>\n<li>Having Django serve downloadable files<br \/>\n<a href=\"https:\/\/stackoverflow.com\/questions\/1156246\/having-django-serve-downloadable-files\">https:\/\/stackoverflow.com\/questions\/1156246\/having-django-serve-downloadable-files<\/a><br \/>\n<a href=\"https:\/\/docs.djangoproject.com\/en\/1.8\/ref\/request-response\/#telling-the-browser-to-treat-the-response-as-a-file-attachment\">https:\/\/docs.djangoproject.com\/en\/1.8\/ref\/request-response\/#telling-the-browser-to-treat-the-response-as-a-file-attachment<\/a><\/li>\n<li><a href=\"https:\/\/blog.csdn.net\/li627528647\/article\/details\/77544136\">Python+Django\u5b9e\u73b0\u6587\u4ef6\u7684\u4e0b\u8f7d<\/a><\/li>\n<li><a href=\"http:\/\/www.jb51.net\/article\/78207.htm\">Python+django\u5b9e\u73b0\u6587\u4ef6\u4e0b\u8f7d<\/a><\/li>\n<li><a href=\"https:\/\/www.zhangshengrong.com\/p\/Z9a28xMkXV\/\">\u8be6\u89e3django\u4e09\u79cd\u6587\u4ef6\u4e0b\u8f7d\u65b9\u5f0f<\/a><\/li>\n<\/ul>\n<p>=END=<\/p>\n","protected":false},"excerpt":{"rendered":"<p>=Start= \u7f18\u7531\uff1a \u5b66\u4e60\u3001\u6574\u7406\u4e00\u4e0b\u6700\u8fd1\u770b\u5230\u7684\u77e5\u8bc6\u70b9\uff0c\u65b9\u4fbf\u4ee5\u540e\u53c2\u8003\u3002 \u6b63\u6587\uff1a \u53c2\u8003\u89e3\u7b54\uff1a \u65b9\u6cd5\u4e00\uff08\u76f4\u63a5Htt [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23,7],"tags":[627,1129,1128,1126,1127],"class_list":["post-3925","post","type-post","status-publish","format-standard","hentry","category-knowledgebase-2","category-programing","tag-django","tag-fileresponse","tag-filewrapper","tag-httpresponse","tag-streaminghttpresponse"],"views":5432,"_links":{"self":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts\/3925","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/comments?post=3925"}],"version-history":[{"count":1,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts\/3925\/revisions"}],"predecessor-version":[{"id":3926,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts\/3925\/revisions\/3926"}],"wp:attachment":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/media?parent=3925"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/categories?post=3925"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/tags?post=3925"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}