264

サイトのユーザーが、直接ダウンロードできないようにパスが隠されているファイルをダウンロードできるようにしたい。

たとえば、URL を次のようにしたいと考えています。http://example.com/download/?f=somefile.txt

サーバー上では、ダウンロード可能なすべてのファイルがフォルダーにあることがわかっています/home/user/files/

URLを見つけて表示するのではなく、Djangoにそのファイルをダウンロード用に提供させる方法はありますか?

4

15 に答える 15

195

「両方の長所」を得るには、S.Lott のソリューションをxsendfile モジュールと組み合わせることができます。djangoはファイル (またはファイル自体) へのパスを生成しますが、実際のファイル サービングは Apache/Lighttpd によって処理されます。mod_xsendfile を設定したら、数行のコードでビューと統合できます。

from django.utils.encoding import smart_str

response = HttpResponse(mimetype='application/force-download') # mimetype is replaced by content_type for django 1.7
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name)
response['X-Sendfile'] = smart_str(path_to_file)
# It's usually a good idea to set the 'Content-Length' header too.
# You can also set any other required headers: Cache-Control, etc.
return response

もちろん、これはサーバーを制御できる場合、またはホスティング会社が mod_xsendfile を既にセットアップしている場合にのみ機能します。

編集:

mimetype は、django 1.7 の content_type に置き換えられました

response = HttpResponse(content_type='application/force-download')  

編集:これnginxを確認するには、X- Sendfileヘッダーの代わりに使用します。X-Accel-Redirectapache

于 2009-07-21T11:57:59.287 に答える
87

「ダウンロード」は、単に HTTP ヘッダーの変更です。

ダウンロードで応答する方法については、http://docs.djangoproject.com/en/dev/ref/request-response/#telling-the-browser-to-treat-the-response-as-a-file-attachmentを参照してください。 .

に必要な URL 定義は 1 つだけです"/download"

リクエストGETまたはPOSTディクショナリに"f=somefile.txt"情報が含まれます。

ビュー関数は単純にベース パスを " f" 値とマージし、ファイルを開き、応答オブジェクトを作成して返します。コードは 12 行未満にする必要があります。

于 2009-07-20T23:20:15.970 に答える
27

S.Lottには「優れた」/シンプルなソリューションがあり、elo80kaには「最良の」/効率的なソリューションがあります。これが「より良い」/中間の解決策です。サーバーのセットアップはありませんが、大きなファイルの場合は、単純な修正よりも効率的です。

http://djangosnippets.org/snippets/365/

基本的に、Djangoは引き続きファイルの提供を処理しますが、すべてを一度にメモリにロードするわけではありません。これにより、サーバーはメモリ使用量を増やすことなく、大きなファイルを(ゆっくりと)提供できます。

繰り返しになりますが、S.LottのX-SendFileは、より大きなファイルに適しています。しかし、それを気にすることができない、またはしたくない場合は、この中間のソリューションを使用すると、面倒なことなく効率を向上させることができます。

于 2010-12-30T19:17:20.437 に答える
13

mod_xsendfile メソッドでは、ファイル名に非 ASCII 文字を使用できないことは前述しました。

このため、名前が URL エンコードされていて、追加のヘッダーがある限り、任意のファイルを送信できるようにする mod_xsendfile 用のパッチを用意しています。

X-SendFile-Encoding: url

も送られます。

http://ben.timby.com/?p=149

于 2011-03-14T17:10:18.967 に答える
7

試してください:https ://pypi.python.org/pypi/django-sendfile/

「Djangoが権限などをチェックした後、ファイルのアップロードをWebサーバー(たとえば、mod_xsendfileを使用したApache)にオフロードするための抽象化。」

于 2011-04-14T06:37:37.400 に答える
6

apacheまたはnginx 本番環境などの一般的なサーバーによって提供される sendfile API を使用する必要があります。何年もの間、ファイルを保護するためにこれらのサーバーの sendfile API を使用していました。次に、この目的のために、開発と運用の両方の目的に適したシンプルなミドルウェア ベースの django アプリを作成しました。ソース コードはこちらからアクセスできます。
更新: 新しいバージョンのpythonプロバイダーではFileResponse、利用可能な場合は django を使用し、lighthttp、caddy から hiawatha までの多くのサーバー実装のサポートも追加します

使用法

pip install django-fileprovider
  • fileproviderアプリをINSTALLED_APPS設定に追加し、
  • 設定fileprovider.middleware.FileProviderMiddlewareに追加MIDDLEWARE_CLASSES
  • 設定FILEPROVIDER_NAMEを本番環境に設定しnginxます。apacheデフォルトではpython開発目的です。

クラスベース ビューまたは関数ビューで、応答ヘッダーX-Fileの値をファイルへの絶対パスに設定します。例えば、

def hello(request):  
   // code to check or protect the file from unauthorized access
   response = HttpResponse()  
   response['X-File'] = '/absolute/path/to/file'  
   return response  

django-fileproviderコードの変更が最小限で済むように実装されています。

Nginx の構成

ファイルを直接アクセスから保護するには、構成を次のように設定できます。

 location /files/ {
  internal;
  root   /home/sideffect0/secret_files/;
 }

ここでは、内部アクセスのみnginxのロケーション URL/files/を設定します。上記の構成を使用している場合は、X-File を次のように設定できます。

response['X-File'] = '/files/filename.extension' 

nginx の設定でこれを行うことで、ファイルは保護され、django からファイルを制御することもできますviews

于 2016-12-12T18:35:40.590 に答える
2

Django は、別のサーバーを使用して静的メディアを提供することをお勧めします (同じマシンで別のサーバーを実行しても問題ありません)。彼らは、 lighttpなどのサーバーの使用を推奨しています。

これは非常に簡単に設定できます。でも。「somefile.txt」が要求に応じて生成される場合 (コンテンツは動的です)、django に提供させたい場合があります。

Django Docs - 静的ファイル

于 2009-07-21T09:49:56.423 に答える
0

私は同じ問題に何度も直面したため、 xsendfile モジュールと認証ビューデコレータdjango-filelibraryを使用して実装しました。独自のソリューションのインスピレーションとして自由に使用してください。

https://github.com/danielsokolowski/django-filelibrary

于 2012-05-01T22:07:51.167 に答える
0

見てみる別のプロジェクト: http://readthedocs.org/docs/django-private-files/en/latest/usage.html 有望に見えますが、まだ自分でテストしていません。

基本的に、プロジェクトは mod_xsendfile 構成を抽象化し、次のようなことができるようにします。

from django.db import models
from django.contrib.auth.models import User
from private_files import PrivateFileField

def is_owner(request, instance):
    return (not request.user.is_anonymous()) and request.user.is_authenticated and
                   instance.owner.pk = request.user.pk

class FileSubmission(models.Model):
    description = models.CharField("description", max_length = 200)
        owner = models.ForeignKey(User)
    uploaded_file = PrivateFileField("file", upload_to = 'uploads', condition = is_owner)
于 2012-01-13T06:18:31.057 に答える
0

https://github.com/johnsensible/django-sendfileを使用して静的 html フォルダーへの保護されたアクセスを提供する: https://gist.github.com/iutinvg/9907731

于 2014-04-01T04:35:39.063 に答える