Jak mogę zwrócić kod stanu HTTP 204 z widoku Django?

82

Chcę zwrócić kod statusu 204 No Content z widoku Django. Jest to odpowiedź na automatyczny POST, który aktualizuje bazę danych i po prostu muszę wskazać, że aktualizacja się powiodła (bez przekierowywania klienta).

Istnieją podklasy HttpResponseobsługujące większość innych kodów, ale nie 204.

Jaki jest najprostszy sposób na zrobienie tego?

Lampa błyskowa
źródło
Nie robiłem tego wcześniej, ale czy próbowałeś ustawić atrybut stanu obiektu odpowiedzi przed zwróceniem odpowiedzi z widoku? Tutaj jest też kolejne SO pytanie na ten temat: stackoverflow.com/questions/408541/ ...
alan

Odpowiedzi:

173
return HttpResponse(status=204)
Steve Mayne
źródło
4
Dzięki. W3C stwierdza, że ​​"odpowiedź 204 NIE MOŻE zawierać treści wiadomości", więc (zakładając, że parametr treści odwzorowuje treść wiadomości), powinna być jednak pusta, prawda?
Flash
1
Dla każdego, kto czyta kod 204 i nie interesuje się tylko kodem 204, możesz użyć treści wiadomości z metodami HTTPResponse Django.
Braden Holt
20

Albo to, na co odpowiedział Steve Mayne, albo stwórz własną, podklasując HttpResponse:

from django.http import HttpResponse

class HttpResponseNoContent(HttpResponse):
    status_code = 204

def my_view(request):
    return HttpResponseNoContent()
rantanplan
źródło
19

Podczas używania renderowania występuje statusargument ze słowa kluczowego.

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

(Zauważ, że w przypadku statusu 204 nie powinno być treści odpowiedzi, ale ta metoda jest przydatna w przypadku innych kodów stanu).

znak
źródło
Czy nie spowodowałoby to jednak przekierowania?
GobSmack
Nie jest potrzebne przekierowanie, powinno działać tak samo jak pierwsza odpowiedź, tylko krótszą składnię. (Użycie kodu statusu 204 do przekierowania byłoby bardzo dziwne, gdyby w ogóle działało).
Mark
Och… Czy istnieje sposób, bym mógł przekazać stan błędu bez ponownego ładowania strony lub przekierowywania na nową stronę? Chcę go użyć, gdy plik, który użytkownik próbuje zapisać, już istnieje. Próbowałem 409 i 422. Ale przekierowują go na nową stronę. Wiem, że AJAX to inne rozwiązanie. Ale zastanawiał się, czy Django miał jakąś sztuczkę.
GobSmack
1
Kody stanu są używane, gdy odwiedzający ładują stronę. Więc muszą już ładować stronę; zmiana kodu nie powoduje dodatkowego przekierowania, ale nadal ładujesz nową stronę. Jeśli są na stronie i chcesz ich o tym poinformować bez ponownego ładowania, to nie sądzę, aby można było zaktualizować kod bieżącej strony (i tak nie sądzę, że byłoby to strasznie przydatne). A więc: jeśli zapiszą formularz, który odeśle ich na nową stronę, możesz wybrać dowolny kod statusu dla strony wyników. Jeśli nie ładuje nowej strony, po prostu pokaż komunikat i zapomnij kod statusu.
Mark
Rozumiem co mówisz. Ale naprawdę muszę po prostu zaktualizować stronę. Myślę więc, że będę musiał użyć AJAX + Django :( Jednak wielkie dzięki!
GobSmack
0

Pozostałe odpowiedzi działają głównie, ale nie generują w pełni zgodnych odpowiedzi HTTP 204, ponieważ nadal zawierają nagłówek treści. Może to skutkować ostrzeżeniami WSGI i jest odbierane przez narzędzia testowe, takie jak Django Web Test.

Oto ulepszona klasa dla zgodnej odpowiedzi HTTP 204. (na podstawie tego biletu 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()
Erik Kalkoken
źródło