DjangoビューからHTTPステータスコード204を返すにはどうすればよいですか?


82

ステータスコードを返したい 204 No ContentDjangoビューから。これは、データベースを更新する自動POSTに応答するものであり、更新が成功したことを示す必要があります(クライアントをリダイレクトせずに)。

HttpResponse他のほとんどのコードを処理するためのサブクラスがありますが、204は処理しません。

これを行う最も簡単な方法は何ですか?


これは以前に行ったことがありませんが、ビューから応答を返す前に、応答オブジェクトのステータス属性を設定してみましたか?また、これに関する別のSOの質問があります:stackoverflow.com/questions/408541/…–
alan

回答:


173
return HttpResponse(status=204)

4
ありがとう。W3Cは、「204応答にはメッセージ本文を含めてはならない」と述べているので(コンテンツパラメータがメッセージ本文にマップされていると仮定して)、空白にする必要があります。
フラッシュ

1
204コードだけに関心がない人は、DjangoのHTTPResponseメソッドでメッセージ本文を使用できます。
ブレーデンホルト


20

Steve Mayneが答えたもの、またはHttpResponseをサブクラス化して独自のものを作成します。

from django.http import HttpResponse

class HttpResponseNoContent(HttpResponse):
    status_code = 204

def my_view(request):
    return HttpResponseNoContent()

19

使用する場合 renderするstatusキーワード引数があります。

return render(request, 'template.html', status=204)

(ステータス204の場合、応答本文は存在しないはずですが、このメソッドは他のステータスコードに役立ちます。)


しかし、これはリダイレクトを引き起こしませんか?
GobSmack 2015

リダイレクトは必要ありません。トップアンサーと同じように、構文を短くする必要があります。(リダイレクトにステータスコード204を使用すると、機能するとしても非常に奇妙になります)。
マーク

ああ..実際にページをリロードしたり、新しいページにリダイレクトしたりせずにエラーステータスを渡す方法はありますか?ユーザーが保存しようとしているファイルが既に存在する場合に使用したい。409&422を試しましたが、新しいページにリダイレクトされます。私はAJAXが他の解決策であることを知っています。しかし、Djangoに何かトリックがあるかどうか疑問に思っていました。
GobSmack 2015

1
ステータスコードは、訪問者がページをロードするときに使用されます。したがって、彼らはすでにページをロードしている必要があります。コードを変更しても余分なリダイレクトは発生しませんが、新しいページを読み込んでいます。それらがページ上にあり、リロードせずに通知したい場合、現在のページのコードを更新する方法はないと思います(とにかくそれがひどく役立つとは思わない)。つまり、新しいページに送信するフォームを保存する場合は、結果ページのステータスコードを選択できます。新しいページが読み込まれない場合は、メッセージを表示してステータスコードを忘れてください。
2015

私はあなたが言っていることを理解します。しかし、私は本当にページを更新する必要があります。だから、私はAJAX + Djangoを使用する必要があると思います:(
でもどうも

0

他の回答はほとんど機能しますが、コンテンツヘッダーがまだ含まれているため、完全に準拠したHTTP204応答は生成されません。これにより、WSGI警告が発生する可能性があり、Django WebTestなどのテストツールによって検出されます。

これは、準拠しているHTTP204応答の改善されたクラスです。(このDjangoチケットに基づく):

from django.http import HttpResponse

class HttpResponseNoContent(HttpResponse):
    """Special HTTP response with no content, just headers.

    The content operations are ignored.
    """

    def __init__(self, content="", mimetype=None, status=None, content_type=None):
        super().__init__(status=204)

        if "content-type" in self._headers:
            del self._headers["content-type"]

    def _set_content(self, value):
        pass

    def _get_content(self, value):
        pass

def my_view(request):
    return HttpResponseNoContent()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.