Wie kann ich den HTTP-Statuscode 204 aus einer Django-Ansicht zurückgeben?

81

Ich möchte den Statuscode 204 No Contentaus einer Django-Ansicht zurückgeben. Es ist eine Antwort auf einen automatischen POST, der eine Datenbank aktualisiert, und ich muss nur angeben, dass die Aktualisierung erfolgreich war (ohne den Client umzuleiten).

Es gibt Unterklassen für HttpResponsedie meisten anderen Codes, jedoch nicht für 204.

Was ist der einfachste Weg, dies zu tun?

Blitz
quelle
Ich habe dies noch nicht getan, aber haben Sie versucht, das Statusattribut des Antwortobjekts festzulegen, bevor Sie die Antwort aus Ihrer Sicht zurückgeben? Auch hier ist eine weitere SO-Frage dazu: stackoverflow.com/questions/408541/…
Alan

Antworten:

172
return HttpResponse(status=204)
Steve Mayne
quelle
4
Vielen Dank. W3C gibt an, dass die Antwort 204 KEINEN Nachrichtentext enthalten darf. Daher sollte sie (vorausgesetzt, der Inhaltsparameter wird dem Nachrichtentext zugeordnet) leer sein, oder?
Flash
1
Für alle Leser, die sich nicht nur mit einem 204-Code befassen, können Sie einen Nachrichtentext mit den HTTPResponse-Methoden von Django verwenden.
Braden Holt
20

Entweder was Steve Mayne geantwortet hat, oder Sie erstellen Ihre eigene, indem Sie HttpResponse unterordnen:

from django.http import HttpResponse

class HttpResponseNoContent(HttpResponse):
    status_code = 204

def my_view(request):
    return HttpResponseNoContent()
Rantanplan
quelle
18

Bei Verwendung von Render gibt es ein statusSchlüsselwortargument.

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

(Beachten Sie, dass im Fall von Status 204 kein Antworttext vorhanden sein sollte, diese Methode jedoch für andere Statuscodes nützlich ist.)

Kennzeichen
quelle
Würde dies nicht zu einer Weiterleitung führen?
GobSmack
Keine Umleitung erforderlich, es sollte dasselbe tun wie die Top-Antwort, nur kürzere Syntax. (Die Verwendung des Statuscodes 204 für eine Umleitung wäre sehr seltsam, wenn es überhaupt funktioniert).
Mark
Oh .. Gibt es eine Möglichkeit, einen Fehlerstatus zu übergeben, ohne die Seite tatsächlich neu zu laden oder auf eine neue Seite umzuleiten? Ich möchte es verwenden, wenn eine Datei, die der Benutzer zu speichern versucht, bereits vorhanden ist. Ich habe 409 & 422 ausprobiert. Aber sie leiten es auf eine neue Seite weiter. Ich weiß, dass AJAX die andere Lösung ist. Aber ich fragte mich, ob Django einen Trick hatte.
GobSmack
1
Statuscodes werden verwendet, wenn Besucher eine Seite laden. Sie müssen also bereits eine Seite laden. Das Ändern des Codes führt nicht zu einer zusätzlichen Weiterleitung, aber Sie laden immer noch eine neue Seite. Wenn sie sich auf einer Seite befinden und Sie sie informieren möchten, ohne sie neu zu laden, gibt es meines Erachtens keine Möglichkeit, den Code der aktuellen Seite zu aktualisieren (ich denke, es wäre sowieso nicht besonders nützlich). Also: Wenn sie ein Formular speichern, das sie an eine neue Seite sendet, können Sie einen beliebigen Statuscode für die Ergebnisseite auswählen. Wenn keine neue Seite geladen wird, zeigen Sie einfach die Nachricht an und vergessen Sie den Statuscode.
Mark
Ich verstehe, was du sagst. Aber ich muss wirklich nur die Seite aktualisieren. Also, ich denke, ich muss AJAX + Django verwenden :( Vielen Dank!
GobSmack
0

Die anderen Antworten funktionieren meistens, erzeugen jedoch keine vollständig kompatiblen HTTP 204-Antworten, da sie immer noch einen Inhaltsheader enthalten. Dies kann zu WSGI-Warnungen führen und wird von Testtools wie Django Web Test erfasst.

Hier ist eine verbesserte Klasse für eine HTTP 204-Antwort, die kompatibel ist. (basierend auf diesem Django Ticket ):

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
quelle