2010-06-11 3 views
60

Wenn ich eine POST-Anfrage in der Django-Datei "views.py" bearbeite, muss ich sie manchmal in eine andere URL umleiten. Diese URL, zu der ich weiterleite, wird von einer anderen Funktion in derselben Django-Datei "views.py" verarbeitet. Gibt es eine Möglichkeit, dies zu tun und die ursprünglichen POST-Daten zu erhalten?Django: Wie umleite ich einen Post und gebe die Post-Daten weiter

UPDATE: Weitere Erklärung, warum ich dies tun möchte. Ich habe zwei Web-Apps (nennen wir sie AppA und AppB), die Daten akzeptieren, die der Benutzer in ein Textfeld eingegeben hat. Wenn der Benutzer auf Senden klickt, werden die Daten verarbeitet und detaillierte Ergebnisse angezeigt. AppA und AppB erwarten unterschiedliche Datentypen. Manchmal veröffentlicht ein Benutzer versehentlich AppB-Daten in AppA. In diesem Fall möchte ich sie zu AppB umleiten und die AppB-Ergebnisse anzeigen oder sie zumindest mit den Daten füllen, die sie in AppA eingegeben haben.

auch:

  • Der Kunde will zwei separate Anwendungen, anstatt sie in nur einer Kombination.

  • Ich kann den Code nicht anzeigen, da er zu einem Client gehört.

UPDATE 2: ich, dass KISS entschieden haben, ist die beste Prinzip hier. Ich habe die beiden Apps zu einem kombiniert, das die Dinge einfacher und robuster macht; Ich sollte den Kunden davon überzeugen können, dass es auch der beste Weg ist. Danke für das tolle Feedback. Wenn ich zwei Apps wie beschrieben verwalten würde, dann denke ich, dass Sessions dafür geeignet sind - dank Matthew J Morrison, der das vorgeschlagen hat. Danke an Dzida als seine Kommentare mich über das Design und die Vereinfachung nachdenken ließen.

+0

tun Sie wirklich eine Umleitung an den Client gesendet werden müssen, oder ist dies etwas, das von nur getan werden kann, eine Funktion aufrufen und alle Post-Daten an sie übergeben? –

+0

Ich muss die URL im Client-Browser ändern, also ist dies der einzige Weg, wie ich das tun kann. – FunLovinCoder

+0

und Sie können nicht nur die gesamte Verarbeitung mit den Post-Daten zuerst, und dann umleiten, nachdem die Tatsache? –

Antwort

45

Wenn Sie ein solches Problem haben, besteht eine geringe Chance, dass Sie Ihre Entwürfe möglicherweise überarbeiten müssen.

Dies ist eine Einschränkung von HTTP, dass POST-Daten nicht mit Weiterleitungen gehen können.

Können Sie beschreiben, was Sie zu erreichen versuchen und vielleicht können wir dann über eine saubere Lösung nachdenken.

Wenn Sie keine Sitzungen verwenden möchten, wie Matthew vorgeschlagen hat, können Sie POST-Parameter in GET an die neue Seite übergeben (beachten Sie einige Einschränkungen wie Sicherheit und maximale Länge der GET-Parameter in der Abfragezeichenfolge).

AKTUALISIEREN zu Ihrem Update :) Es klingt komisch für mich, dass Sie 2 Web-Apps haben und diese Apps verwenden eine views.py (habe ich Recht?). Wie auch immer, ziehen Sie in Erwägung, Ihre Daten von POST in GET an die richtige Ansicht zu übergeben (falls die Daten natürlich nicht sensitiv sind).

+2

Ich kann sehen, was er zu tun versucht, könnte gültig sein, wenn er versucht, ein abgelaufenes Login zu handhaben, das einen Benutzer zwingen wird, sich einzuloggen, nachdem er ein Formular abgeschickt hat ... in diesem Fall wird er behalten wollen die Daten, die übermittelt wurden und den Benutzer nicht zwingen, nach Abschluss des Anmeldebildschirms alle Daten erneut einzugeben. –

+0

Ich bin mir nicht sicher, ob ich den Punkt verstanden habe, aber in diesem Fall kann die Login-Operation von der ersten Ansicht mit wenig Code-Änderung und ohne unnötige Weiterleitungen durchgeführt werden. Es wäre großartig, vorhandenen Code zu lesen, um genauere Ratschläge zu geben. – dzida

+0

Ich sage, wenn Sie ein Formular abschicken, und Sie nicht eingeloggt sind, werden Sie zu einem Login-Formular umgeleitet ... in diesem Szenario werden Sie verlieren, was auch immer Sie eingereicht haben. Ich stimme zu, dass ich einen vorhandenen Code sehen kann. –

40

Ich denke, wie würde ich wahrscheinlich diese Situation behandeln würde, um die Post-Daten in Sitzung zu speichern, dann entfernen Sie es, wenn ich es nicht mehr brauche. Auf diese Weise kann ich nach einer Weiterleitung auf die ursprünglichen Post-Daten zugreifen, obwohl dieser Post weg ist.

Funktioniert das für das, was Sie versuchen zu tun?

Hier ist ein Codebeispiel von dem, was ich vorschlage: (beachten Sie dies ist nicht getestet Code) im Auge

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 zu halten ... wenn Sie dies tun, und auch Hochladen von Dateien, würde ich es nicht so machen.

+1

Ich habe noch nie Sitzungen benutzt, aber ich werde mir das mal ansehen. – FunLovinCoder

+1

dies ist nicht die beste Praxis, aber immer noch hilft. Ich denke, für dieses Thema werden wir nichts Schöneres bekommen. –

+0

@GuilhermeDaviddaCosta Warum sagen Sie, dass es nicht die beste Praxis ist? Kannst du uns einen Hinweis geben? –

0

Wenn Sie eine Weiterleitung nach der Verarbeitung des POST zu AppB verwenden, können Sie tatsächlich mit dem Aufruf der AppB Methode aus der AppA Methode.

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/') 

Dieses eine transparente Erfahrung für den Endverbraucher ergeben sollte, und den Client, die Sie kennen wahrscheinlich nie den Unterschied gemietet werden.

Wenn Sie nach dem POST nicht weiterleiten, machen Sie sich keine Sorgen wegen doppelter Daten, weil der Benutzer die Seite aktualisiert hat?

+0

Es wäre toll, wenn eine einfache Lösung wie diese funktioniert. Allerdings muss ich nach der Verarbeitung der Daten detaillierte Ergebnisse anzeigen. Dies würde Sitzungen erfordern (wie von Matthew J Morrison vorgeschlagen), nicht wahr? – FunLovinCoder

+1

Sie können es auf drei Arten tun. # 1, speichern Sie die Daten in der Datenbank und übergeben Sie den 'pk' des neuen Eintrags, wenn Sie umleiten. # 2, speichern Sie die Daten im Cache-Backend und übergeben Sie den Schlüssel erneut. # 3, speichern Sie es in der Sitzung. Für eine Web-App ist das völlig normal, auch wenn es nur temporär ist. Wenn die Formulardaten nicht-trivial zu analysieren sind, würde es das System auch schneller machen, wenn die Ausgabe bereits zwischengespeichert war. –

14

Sie müssen HTTP 1.1 Temporary Redirect (307) verwenden.

Leider Django redirect() und HTTPResponseRedirect (permanent) Zurückkehren nur 301 oder 302. Sie haben es selbst zu 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 django.http module.

Edit:

auf neueren Versionen Django, ändern iri_to_uri Import:

from django.utils.encoding import iri_to_uri 
+0

Neuere Versionen von Django haben eine permanente Umleitung HttpResponsePermanentRedirect, aber nicht sicher, ob es das ursprüngliche Problem löst https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpResponsePermanentRedirect – JiminyCricket

+0

permanent ist 301, also, nein. – Lloeki

1

einfach Ihre neue Ansicht von Ihrem alten Ansicht rufen Sie die gleiche Anfrage Objekt verwenden. Natürlich wird es nicht zu einer Umleitung als solche führen, aber wenn Sie nur daran interessiert sind, Daten von einer Ansicht in die andere zu übertragen, dann sollte es funktionieren.
Ich habe das folgende Snippet getestet und es funktioniert.

Render(request,"your template path",  {'vad name' : var value} 

Sie Vars in Vorlage recive können:

{% If var name %} 
{{ var name }} 
{% endif %} 
+0

Ich habe diese Lösung verwendet und es funktionierte ohne Probleme. – guival

0

können Sie und Kontext mit damit verwenden machen.Es ist sehr einfach zu implementieren

pip install requests 

dann können Sie

in Ihre Ansichten Importanforderungen

import requests 

zu veröffentlichen Daten URLs mit beliebigen Verfahren und Übertragung von Daten aufrufen, folgen Sie dem Format

r = requests.post('http://yourdomain/path/', data = {'key':'value'}) 

um die absolute URL in der Django-Ansicht zu erhalten, verwenden Sie

request.build_absolute_uri(reverse('view_name'))

So ist die django Ansicht Code sieht aus wie

r = requests.post(
      request.build_absolute_uri(reverse('view_name')), 
      data = {'key':'value'} 
    ) 

wo r ist das Response-Objekt mit status_code und content Attribut. r.status_code gibt den Statuscode (bei Erfolg wird es 200 sein) und r.content gibt den Körper der Antwort. Es gibt eine json-Methode (r.json()), die als Reaktion auf JSON-Format konvertieren

requests

requests.post

5

Verwendung requests Paket

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 
Verwandte Themen