Django1.3は許容範囲です。したがって、request.raw_post_dataまたはrequest.read()(または他のより良いアクセス方法)を使用して何かを行うことができます。何か案は?
触れたくはありませんrequest.raw_post_data
。これは、リクエストの本文全体をメモリに読み込むことを意味します。これは、ファイルのアップロードについて話している場合、非常に大量になる可能性があるため、これrequest.read()
が方法です。これはDjango<=1.2でも実行できますがHttpRequest
、プライベートインターフェイスを使用する正しい方法を見つけるために掘り下げてみる必要があります。これは、コードがDjango>=1.3と互換性があることを確認するための実際のドラッグです。 。
クラスの既存のファイルアップロード動作の部分MultiPartParser
を複製することをお勧めします。
- からアップロードハンダーを取得
request.upload_handlers
します(デフォルトではMemoryFileUploadHandler
&になりますTemporaryFileUploadHandler
)
HttpRequest
リクエストのコンテンツの長さを決定します(またはでContent-Lengthを検索MultiPartParser
して、これを行う正しい方法を確認します)。
- アップロードされたファイルのファイル名を決定するには、URLの最後のパス部分を使用してクライアントに指定させるか、
Content-Disposition
ヘッダーの「filename=」部分に指定させます。
- ハンドラーごと
handler.new_file
に、関連する引数を使用して呼び出します(フィールド名のモックアップ)
request.read()
各チャンクを使用して呼び出し、チャンクでリクエスト本文を読み取りhandler.receive_data_chunk()
ます。
- ハンドラー呼び出しごと
handler.file_complete()
に、値が返される場合は、アップロードされたファイルです。
送信されているもののmimeタイプを推測するにはどうすればよいですか?私が正しく理解していれば、PUT本体はプレリュードのない単なるファイルです。したがって、ユーザーがヘッダーでmimeタイプを指定する必要がありますか?
クライアントにContent-Typeヘッダーで指定させるか、Pythonのmimetypeモジュールを使用してメディアタイプを推測します。
私はあなたがこれをどのようにやっていくのかを知りたいと思います-それは私が自分自身を調べることを意味していたことです、それがどうなるかを私に知らせてくれるコメントがあれば素晴らしいです!
要求に応じてNinefingersによって編集されます。これは私が行ったことであり、上記とdjangoソースに完全に基づいています。
upload_handlers = request.upload_handlers
content_type = str(request.META.get('CONTENT_TYPE', ""))
content_length = int(request.META.get('CONTENT_LENGTH', 0))
if content_type == "":
return HttpResponse(status=400)
if content_length == 0:
# both returned 0
return HttpResponse(status=400)
content_type = content_type.split(";")[0].strip()
try:
charset = content_type.split(";")[1].strip()
except IndexError:
charset = ""
# we can get the file name via the path, we don't actually
file_name = path.split("/")[-1:][0]
field_name = file_name
ここでAPIを定義しているので、クロスブラウザーのサポートは問題ではありません。私のプロトコルに関する限り、正しい情報を提供しないことは壊れた要求です。私は、言いたいのかimage/jpeg; charset=binary
、存在しない文字セットを許可するのかについて、2つの考えを持っています。いずれにせよ、私はContent-Type
クライアント側の責任として設定を有効に置いています。
同様に、私のプロトコルでは、ファイル名が渡されます。field_name
パラメーターの目的がわからず、ソースから多くの手がかりが得られませんでした。
以下で起こることは、実際には見た目よりもはるかに単純です。各ハンドラーに、生の入力を処理するかどうかを尋ねます。上記の著者が述べているように、あなたはデフォルトでMemoryFileUploadHandler
&を持っTemporaryFileUploadHandler
ています。さて、(さまざまな設定に基づいて)ファイルを処理するかどうかの決定MemoryFileUploadHandler
を作成するように求められたときに、それがわかります。new_file
実行することを決定した場合は、例外をスローします。それ以外の場合は、ファイルを作成せず、別のハンドラーに引き継がせます。
目的が何であったかはわかりませんcounters
が、ソースからは遠ざけています。残りは簡単なはずです。
counters = [0]*len(upload_handlers)
for handler in upload_handlers:
result = handler.handle_raw_input("",request.META,content_length,"","")
for handler in upload_handlers:
try:
handler.new_file(field_name, file_name,
content_type, content_length, charset)
except StopFutureHandlers:
break
for i, handler in enumerate(upload_handlers):
while True:
chunk = request.read(handler.chunk_size)
if chunk:
handler.receive_data_chunk(chunk, counters[i])
counters[i] += len(chunk)
else:
# no chunk
break
for i, handler in enumerate(upload_handlers):
file_obj = handler.file_complete(counters[i])
if not file_obj:
# some indication this didn't work?
return HttpResponse(status=500)
else:
# handle file obj!