アップロードファイルとアップロードハンドラ

アップロードファイル

class UploadedFile

ファイルアップロード中、実際のファイルデータは request.FILES に保存されます。この辞書の各エントリーは UploadedFile オブジェクト(またはそのサブクラス)です。これはアップロードされたファイルのラッパーです。アップロードされたコンテンツにアクセスするために、通常、以下のメソッドのいずれかを使用します:

UploadedFile.read()

アップロードされたデータ全体をファイルから読み込む。このメソッドには注意が必要です。アップロードされたファイルが巨大な場合、それをメモリに読み込もうとするとシステムを圧迫する可能性があります。おそらく代わりに chunks() を使うことになるでしょう。

UploadedFile.multiple_chunks(chunk_size=None)

アップロードされたファイルが、複数のチャンクに分けて読み込む必要があるほど大きい場合に True を返します。デフォルトでは2.5MB以上のファイルですが、設定可能です。

UploadedFile.chunks(chunk_size=None)

ファイルのチャンクを返すジェネレータです。multiple_chunks()True の場合、 read() の代わりにこのメソッドをループで使用すべきです。

実際には、常に chunks() を使用するのが最も簡単です。 read() を使用する代わりに chunks() をループ処理することで、大きなファイルがシステムのメモリを圧迫しないようにできます。

UploadedFile の有用な属性は次の通りです:

UploadedFile.name

アップロードされたファイルの名前 (例: my_file.txt)。

UploadedFile.size

アップロードされたファイルのサイズ(バイト単位)。

UploadedFile.content_type

ファイルと共にアップロードされるコンテンツタイプのヘッダ (例: text/plainapplication/pdf)。ユーザーから提供されるデータのように、アップロードされたファイルが実際にこのタイプであると信頼すべきではありません。依然として、ファイルがコンテンツタイプヘッダが示すコンテンツを含んでいることを検証する必要があります。"信頼するが検証せよ" です。

UploadedFile.content_type_extra

content-type ヘッダーに渡される追加のパラメータを含む辞書です。通常、Google App Engine などのサービスがファイルのアップロードを取り扱っている場合に提供されます。その結果、ハンドラはアップロードされたファイル内容を受信しないかもしれず、代わりにファイルへの URL や他のポインターを受け取ります (RFC 2388 を参照)。

UploadedFile.charset

text/* コンテンツタイプについては、ブラウザが提供する文字セット(例えば utf8)です。ここでも、"信頼するが検証せよ" が最良の方針です。

注釈

通常の Python ファイルのように、アップロードされたファイルをイテレートすることで、ファイルを一行ずつ読むことができます:

for line in uploadedfile:
    do_something_with(line)

行は ユニバーサル改行 によって分割されます。以下のものが行の終わりとして認識されます: Unix の改行規則 '\n'、Windowsの改行規則 '\r\n'、古い Macintosh の改行規則 '\r'

UploadedFile のサブクラスには以下が含まれます:

class TemporaryUploadedFile

一時的な場所にアップロードされたファイル (つまり、stream-to-disk)。このクラスは、 TemporaryFileUploadHandler によって使用されます。 UploadedFile のメソッドに加えて、1つの追加メソッドを持っています:

TemporaryUploadedFile.temporary_file_path()

一時アップロードされたファイルの完全なパスを返します。

class InMemoryUploadedFile

メモリへのアップロードされたファイル(つまり、stream-to-memory)。このクラスは MemoryFileUploadHandler によって使用されます。

ビルトインのアップロードハンドラ

MemoryFileUploadHandlerTemporaryFileUploadHandler は、小さなファイルをメモリに読み込み、大きなファイルをディスクに保存するDjangoのデフォルトのファイルアップロードの動作を提供します。これらは django.core.files.uploadhandler に位置しています。

class MemoryFileUploadHandler

小さいファイル用にアップロードをメモリにストリームするためのファイルアップロードハンドラ。

class TemporaryFileUploadHandler

TemporaryUploadedFile を使ってデータを一時ファイルにストリームするアップロードハンドラ。

アップロードハンドラをカスタマイズする

class FileUploadHandler

全てのファイルアップロードハンドラは、django.core.files.uploadhandler.FileUploadHandler のサブクラスとなります。アップロードハンドラはいつでも好きなときに定義できます。

必要なメソッド

カスタマイズされたファイルアップロードハンドラでは、以下のメソッドを定義する 必要があります

FileUploadHandler.receive_data_chunk(raw_data, start)

ファイルアップロードから、データの "chunk" を受け取ります。

raw_data はアップロードされたデータを含むバイト文字列です。

start はこの raw_data チャンクが始まる、ファイル内での位置です。

あなたが返すデータは、その後のアップロードハンドラの receive_data_chunk メソッドに渡されます。 この方法で、1 つのハンドラは他のハンドラの「フィルタ」になることができます。

receive_data_chunk から None を返し、残りのアップロードハンドラがこのチャンクを取得するのを短絡します。 これは、アップロードしたデータを自分で保存しておき、将来のハンドラでデータのコピーを保存したくない場合に便利です。

StopUpload または SkipFile 例外を発生させると、アップロードが中止されるか、ファイルが完全にスキップされます。

FileUploadHandler.file_complete(file_size)

ファイルのアップロードが完了したときに呼ばれます。

ハンドラーは request.FILES に格納される UploadedFile オブジェクトを返すべきです。またハンドラーは、UploadedFile オブジェクトが後続のアップロードハンドラーから来るべきであることを示すために None を返すこともできます。

省略可能なメソッド

独自のアップロードハンドラは、以下の省略可能なメソッドや属性を定義できます:

FileUploadHandler.chunk_size

Django がメモリに格納してハンドラに送り込む "chunks" のサイズです (byte で表されます)。 つまり、この属性は FileUploadHandler.receive_data_chunk に渡されるチャンクのサイズをコントロールします。

パフォーマンスを最大限にするために、チャンクサイズは 4 で割り切れる必要があり、2 GB (231 bytes) を超えてはいけません。 複数のハンドラによってチャンクサイズが複数ある場合、Django はハンドラで定義された最小のチャンクサイズを使用します。

デフォルトは 64*210 bytes、つまり 64 KB です。

FileUploadHandler.new_file(field_name, file_name, content_type, content_length, charset, content_type_extra)

新しいファイルのアップロード開始を通知するコールバックです。 アップロードハンドラにデータが送られる前に呼び出されます。

field_name は、ファイル <input> フィールドの文字列名です。

file_name はブラウザによって提供されるファイル名です。

content_type は、ブラウザによって提供される MIME タイプです -- 例: 'image/jpeg'

content_length は、ブラウザによって与えられる画像の長さです。提供されずに None となることがあります。

charset は、ブラウザによって与えられる文字セットです (例: utf8)。content_length のように、提供されないことがあります。

content_type_extra は、content-type からの、ファイルについての追加情報です。UploadedFile.content_type_extra を参照してください。

このメソッドは、将来のハンドラがこのファイルをハンドリングするのを防ぐため、StopFutureHandlers 例外を投げます。

FileUploadHandler.upload_complete()

全てのアップロード (全てのファイル) が完了したことを通知するコールバックです。

FileUploadHandler.upload_interrupted()

アップロードが中断されたことを通知するコールバック。例えば、ユーザーがファイルアップロード中にブラウザを閉じたときなど。

FileUploadHandler.handle_raw_input(input_data, META, content_length, boundary, encoding)

ハンドラに対して、生の HTTP インプットのパースを完全にオーバーライドできるようにします。

input_data は、read() をサポートするファイルのようなオブジェクトです。

META は、request.META と同じオブジェクトです。

content_length は、input_data 内のデータの長さです。input_data から content_length バイト以上を読み出さないでください。

boundary は、このリクエストの MIME boundary です。

encoding は、リクエストのエンコーディングです。

アップロードハンドリングを継続したいとき、None を返します。もしくはリクエストに適した新しいデータ構造を直接返したいとき、 (POST, FILES) のタプルを返します。

Back to Top