Wenn ich eine POST-Anfrage in der Datei Django views.py verarbeite, muss ich sie manchmal auf eine andere URL umleiten. Diese URL, zu der ich umleitung, wird von einer anderen Funktion in derselben Django views.py-Datei verarbeitet. Gibt es eine Möglichkeit, dies zu tun und die ursprünglichen POST-Daten beizubehalten?
UPDATE: Weitere Erklärungen, warum ich das tun möchte. Ich habe zwei Web-Apps (nennen wir sie AppA und AppB), die vom Benutzer in ein Textfeld eingegebene Daten akzeptieren. Wenn der Benutzer auf Senden klickt, werden die Daten verarbeitet und detaillierte Ergebnisse angezeigt. AppA und AppB erwarten unterschiedliche Datentypen. Manchmal sendet ein Benutzer fälschlicherweise Daten vom Typ AppB an AppA. In diesem Fall möchte ich sie zu AppB umleiten und die AppB-Ergebnisse anzeigen oder zumindest mit den Daten füllen lassen, die sie in AppA eingegeben haben.
Ebenfalls:
Der Client möchte zwei separate Apps, anstatt sie zu nur einer zu kombinieren.
Ich kann den Code nicht anzeigen, da er einem Client gehört.
UPDATE 2: Ich habe entschieden, dass KISS hier das beste Prinzip ist. Ich habe die beiden Apps zu einer zusammengefasst, was die Dinge einfacher und robuster macht. Ich sollte in der Lage sein, den Kunden davon zu überzeugen, dass dies auch der beste Weg ist. Vielen Dank für das tolle Feedback. Wenn ich zwei Apps wie beschrieben warten würde, wären Sitzungen meiner Meinung nach der richtige Weg, dies zu tun - danke an Matthew J Morrison, der dies vorgeschlagen hat. Dank Dzida als seine Kommentare haben mich über das Design und die Vereinfachung nachgedacht.
id
in GET verwiesen wird , und hat auch Zugriff auf andere von POST übermittelte Daten.Antworten:
Wenn Sie mit einem solchen Problem konfrontiert sind, besteht eine geringe Wahrscheinlichkeit, dass Sie Ihre Entwürfe überarbeiten müssen.
Dies ist eine Einschränkung von HTTP, die POST-Daten nicht mit Weiterleitungen verbinden können.
Können Sie beschreiben, was Sie erreichen wollen, und vielleicht können wir dann über eine ordentliche Lösung nachdenken.
Wenn Sie keine Sitzungen verwenden möchten, wie von Matthew vorgeschlagen, können Sie POST-Parameter in GET an die neue Seite übergeben (beachten Sie einige Einschränkungen wie die Sicherheit und die maximale Länge der GET-Parameter in der Abfragezeichenfolge).
UPDATE zu Ihrem Update :) Es klingt seltsam für mich, dass Sie 2 Web-Apps haben und diese Apps eine views.py verwenden (habe ich recht?). Überlegen Sie auf jeden Fall, ob Sie Ihre Daten von POST in GET an die richtige Ansicht übergeben möchten (falls die Daten natürlich nicht vertraulich sind).
quelle
Ich denke, wie ich mit dieser Situation wahrscheinlich umgehen würde, wäre, die Post-Daten in der Sitzung zu speichern und sie dann zu entfernen, wenn ich sie nicht mehr benötige. Auf diese Weise kann ich nach einer Weiterleitung auf die ursprünglichen Postdaten zugreifen, obwohl dieser Post weg ist.
Funktioniert das für das, was Sie versuchen zu tun?
Hier ist ein Codebeispiel dessen, was ich vorschlage: (Denken Sie daran, dass dies ungetesteter Code ist.)
def some_view(request): #do some stuff request.session['_old_post'] = request.POST return HttpResponseRedirect('next_view') def next_view(request): old_post = request.session.get('_old_post') #do some stuff using old_post
Eine andere Sache, die Sie beachten sollten ... Wenn Sie dies tun und auch Dateien hochladen, würde ich es nicht so machen.
quelle
Sie müssen eine temporäre HTTP 1.1-Umleitung (307) verwenden.
Leider geben Django
redirect()
undHTTPResponseRedirect
(permanent) nur 301 oder 302 zurück. Sie müssen es selbst implementieren:from django.http import HttpResponse, iri_to_uri class HttpResponseTemporaryRedirect(HttpResponse): status_code = 307 def __init__(self, redirect_to): HttpResponse.__init__(self) self['Location'] = iri_to_uri(redirect_to)
Siehe auch das Modul django.http .
Bearbeiten:
Ändern Sie
iri_to_uri
in den neuesten Django-Versionen den Import in:from django.utils.encoding import iri_to_uri
quelle
Verwenden Sie
requests
package.Its sehr einfach zu implementierenpip install requests
Dann können Sie beliebige URLs mit einer beliebigen Methode aufrufen und Daten übertragen
Importieren Sie in Ihren Ansichten Anfragen
import requests
Um Daten zu veröffentlichen, folgen Sie dem Format
r = requests.post('http://yourdomain/path/', data = {'key':'value'})
Verwenden Sie, um die absolute URL in der Django-Ansicht zu erhalten
request.build_absolute_uri(reverse('view_name'))
So sieht der Django-Ansichtscode aus
r = requests.post( request.build_absolute_uri(reverse('view_name')), data = {'key':'value'} )
Wo
r
ist das Antwortobjekt mitstatus_code
undcontent
Attribut.r.status_code
gibt den Statuscode an (bei Erfolg sind es 200) undr.content
gibt den Antworttext an. Es gibt eine json-Methode (r.json()
), die die Antwort in das json-Format konvertiertAnfragen
request.post
quelle
Rufen Sie einfach Ihre neue Ansicht aus Ihrer alten Ansicht mit demselben Anforderungsobjekt auf. Natürlich führt dies nicht zu einer Umleitung als solche, aber wenn Sie nur Daten von einer Ansicht in die andere übertragen möchten, sollte dies funktionieren.
Ich habe das folgende Snippet getestet und es funktioniert.
from django.views.generic import View class MyOldView(View): def post(self, request): return MyNewView().post(request) class MyNewView(View): def post(self, request): my_data = request.body print "look Ma; my data made it over here:", my_data
quelle
Sie können damit Rendering und Kontext verwenden :
Render(request,"your template path", {'vad name' : var value}
Sie können Vars in der Vorlage empfangen:
quelle
Ich hatte kürzlich ein ähnliches Problem.
Grundsätzlich hatte ich ein Formular A, nach dem Absenden wurde ein anderes Formular B angezeigt, das einige Ergebnisse + ein Formular enthält. Beim Senden von B wollte ich dem Benutzer eine Warnung anzeigen und den Benutzer nur auf B halten.
Ich habe dies gelöst, indem ich die Ergebnisse in einem
<output>
Feld in B angezeigt habe.<output name="xyz" value="xyz">{{xyz}}</output>
Und ich habe die gleiche Ansicht für A-> B und B-> B verwendet. Jetzt musste ich nur noch unterscheiden, ob die Anfrage von A oder B kommt und entsprechend rendern.
def view1(request): if "xyz" in request.POST: # request from B # do some processing return render(request, 'page.html', {"xyz":request.POST["xyz"]}) else: # request from A res = foo() # some random function return render(request, 'page.html', {"xyz":res})
Dies funktioniert jedoch nur, wenn Form B klein und nicht so dynamisch ist.
quelle
Wenn Sie nach der Verarbeitung des POST eine Umleitung verwenden
AppB
, können Sie dieAppB
Methode tatsächlich von der Methode aus aufrufenAppA
.Ein Beispiel:
def is_appa_request(request): ## do some magic. return False or True is_appb_request = is_appa_request def AppA(request): if is_appb_request(request): return AppB(request) ## Process AppA. return HttpResponseRedirect('/appa/thank_you/') def AppB(request): if is_appa_request(request): return AppA(request) ## Process AppB. return HttpResponseRedirect('/appb/thank_you/')
Dies sollte eine transparente Erfahrung für den Endbenutzer ergeben, und der Kunde, der Sie eingestellt hat, wird den Unterschied wahrscheinlich nie erfahren.
Wenn Sie nach dem POST nicht umleiten, sind Sie dann nicht besorgt über doppelte Daten, weil der Benutzer die Seite aktualisiert?
quelle
pk
den neuen Eintrag, wenn Sie umleiten. # 2, speichern Sie die Daten imcache
Backend und übergeben Sie den Schlüssel erneut. # 3, speichern Sie es in der Sitzung. All dies ist für eine Web-App völlig normal, auch wenn es nur vorübergehend ist. Wenn die zu analysierenden Formulardaten nicht trivial sind, würde dies das System auch schneller machen, wenn die Ausgabe bereits zwischengespeichert wäre.