ブラウザ拡張
「オーバーロードされたPOSTには、議論の余地のない2つの用途があります。1つ目は、PUTまたはDELETEをサポートしていないWebブラウザなどのクライアントのためにHTTPの統一インターフェースを*シミュレート*することです」
— RESTful Webサービス、Leonard Richardson&Sam Ruby。
ブラウザブルAPIを機能させるため、REST frameworkが提供する必要があるブラウザ拡張がいくつかあります。
バージョン3.3.0以降、これらはajax-formライブラリを使用してJavaScriptで有効になっています。
ブラウザベースのPUT、DELETEなど...
AJAXフォームライブラリは、HTMLフォームでのブラウザベースのPUT
、DELETE
、およびその他のメソッドをサポートしています。
ライブラリを含めた後、次のようにフォームのdata-method
属性を使用します。
<form action="/" data-method="PUT">
<input name='foo'/>
...
</form>
3.3.0より前は、このサポートはJavaScriptベースではなくサーバーサイドでした。メソッドオーバーロードスタイル(Ruby on Railsで使用されている)は、リクエストの解析で微妙な問題が発生するため、サポートされなくなりました。
ブラウザベースの非フォームコンテンツの送信
JSONなどのコンテントタイプのブラウザベースの送信は、data-override='content-type'
およびdata-override='content'
属性を持つフォームフィールドを使用するAJAXフォームライブラリでサポートされています。
例えば
<form action="/">
<input data-override='content-type' value='application/json' type='hidden'/>
<textarea data-override='content'>{}</textarea>
<input type="submit"/>
</form>
3.3.0より前は、このサポートはJavaScriptベースではなくサーバーサイドでした。
URLベースのフォーマットサフィックス
REST frameworkは、?format=json
スタイルのURLパラメータを使用できます。これは、ビューからどのコンテントタイプを返すかを決定するための便利なショートカットになります。
この動作は、URL_FORMAT_OVERRIDE
設定を使用して制御されます。
HTTPヘッダーベースのメソッドオーバーライド
バージョン3.3.0より前は、リクエストメソッドをオーバーライドするためにセミ拡張ヘッダーX-HTTP-Method-Override
がサポートされていました。この動作はコアではなくなりましたが、必要に応じてミドルウェアを使用して追加できます。
例えば
METHOD_OVERRIDE_HEADER = 'HTTP_X_HTTP_METHOD_OVERRIDE'
class MethodOverrideMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.method == 'POST' and METHOD_OVERRIDE_HEADER in request.META:
request.method = request.META[METHOD_OVERRIDE_HEADER]
return self.get_response(request)
URLベースのAcceptヘッダー
バージョン3.3.0までは、REST frameworkには?accept=application/json
スタイルのURLパラメータの組み込みサポートが含まれており、Accept
ヘッダーをオーバーライドすることができました。
コンテンツネゴシエーションAPIの導入以来、この動作はコアには含まれなくなりましたが、必要に応じてカスタムコンテンツネゴシエーションクラスを使用して追加できます。
例えば
class AcceptQueryParamOverride()
def get_accept_list(self, request):
header = request.META.get('HTTP_ACCEPT', '*/*')
header = request.query_params.get('_accept', header)
return [token.strip() for token in header.split(',')]
HTML5はPUTおよびDELETEフォームをサポートしていませんか?
いいえ。かつてはPUT
およびDELETE
フォームをサポートすることを目的としていましたが、後に仕様から削除されました。 PUT
とDELETE
のサポート、およびフォームエンコードデータ以外のコンテントタイプのサポート方法については、現在も議論が続いています。