2010-06-11 16 views
60

Al procesar una solicitud POST en el archivo Django views.py, a veces necesito redirigirlo a otra URL. Esta URL a la que estoy redireccionando es manejada por otra función en el mismo archivo Django views.py. ¿Hay alguna forma de hacerlo y mantener los datos POST originales?Django: cómo redirijo una publicación y paso los datos de la publicación

ACTUALIZACIÓN: Más explicación de por qué quiero hacer esto. Tengo dos aplicaciones web (llamémoslas AppA y AppB) que aceptan datos ingresados ​​en un campo de texto por el usuario. Cuando el usuario hace clic en enviar, los datos se procesan y se muestran resultados detallados. AppA y AppB esperan diferentes tipos de datos. A veces, un usuario publica erróneamente datos de tipo AppB en AppA. Cuando esto suceda, quiero redirigirlos a AppB y mostrar los resultados de AppB o al menos completarlos con los datos que ingresaron en AppA.

también:

  • El cliente quiere dos aplicaciones por separado en lugar de la combinación de ellos en uno solo.

  • No puedo mostrar el código ya que pertenece a un cliente.

ACTUALIZACIÓN 2: He decidido que beso es el mejor principio aquí. He combinado las dos aplicaciones en una que hace que las cosas sean más simples y más robustas; Debería poder convencer al cliente que es la mejor manera de ir también. Gracias por todos los excelentes comentarios. Si tuviera que mantener dos aplicaciones como las descritas, creo que las sesiones serían la forma de hacerlo, gracias a Matthew J Morrison por sugerir eso. Gracias a Dzida porque sus comentarios me hicieron pensar en el diseño y la simplificación.

+0

es lo que realmente necesita enviar una redirección al cliente, o esto es algo que se puede hacer con sólo llamar a una función y pasarle todos los datos de la publicación? –

+0

Necesito cambiar la URL en el navegador del cliente, así que esta es la única manera que tengo de hacerlo. – FunLovinCoder

+0

y no puedes hacer todo el procesamiento con los datos de la publicación primero, y luego redirigir después del hecho? –

Respuesta

45

Si se enfrenta a este tipo de problema, existe una pequeña posibilidad de que tenga que revisar sus diseños.

Esta es una restricción de HTTP que los datos POST no pueden ir con los redireccionamientos.

¿Puede describir lo que está tratando de lograr y tal vez entonces podamos pensar en alguna solución ordenada?

Si no desea usar las sesiones como Matthew sugirió, puede pasar los parámetros POST en GET a la nueva página (considere algunas limitaciones como la seguridad y la longitud máxima de los parámetros GET en la cadena de consulta).

ACTUALIZAR a su actualización :) Me parece extraño que tenga 2 aplicaciones web y esas aplicaciones usan un views.py (¿estoy en lo cierto?). De todos modos, considere pasar sus datos de POST en GET a la vista adecuada (en caso de que los datos no sean sensibles por supuesto).

+2

Puedo ver lo que intenta hacer si intenta manejar un inicio de sesión caducado que forzará a un usuario a iniciar sesión después de enviar un formulario ... en ese caso, va a querer conservar los datos que se enviaron y no obligan al usuario a volver a ingresar todo después de completar la pantalla de inicio de sesión. –

+0

No estoy seguro de si entendí el punto, pero en este caso la operación de inicio de sesión se puede realizar en la primera vista con poca modificación del código y sin hacer redirecciones innecesarias. Sería genial leer el código existente para hacer consejos más precisos. – dzida

+0

Estoy diciendo que si envía un formulario y no está conectado, lo van a redirigir a un formulario de inicio de sesión ... en ese caso, perderá lo que haya enviado. Estoy de acuerdo en poder ver algún código existente. –

40

Creo que la forma en que probablemente manejaría esta situación sería guardar los datos de la publicación en sesión y luego eliminarlos cuando ya no los necesite. De esa forma, puedo acceder a los datos de publicación originales después de una redirección aunque esa publicación ya no esté.

Funciona para lo que estás tratando de hacer?

Aquí es un ejemplo de código de lo que estoy sugiriendo: (tener en cuenta que es de código no probado)

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 

Otra cosa a tener en cuenta ... si está haciendo esto y también cargando archivos, no lo haría de esta manera.

+1

Nunca he usado sesiones, pero voy a echarle un vistazo gracias. – FunLovinCoder

+1

esta no es la mejor práctica, pero aún así ayuda. Supongo que para este problema no obtendremos nada más bonito. –

+0

@GuilhermeDaviddaCosta ¿por qué dices que no es una buena práctica? ¿Puedes darnos una pista? –

0

Si está utilizando una redirección después de procesar la POST a AppB, puede salirse con la suya llamando al método AppB desde el método AppA.

Un ejemplo:

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

Esto debería producir una experiencia transparente para el usuario final, y el cliente que contrató es probable que nunca sepamos la diferencia.

Si no está redirigiendo después del POST, ¿no le preocupan los datos duplicados debido a que el usuario actualiza la página?

+0

Sería genial si funcionara una solución simple como esta. Sin embargo, necesito mostrar resultados detallados después de procesar los datos. Esto requeriría sesiones (como lo propuso Matthew J Morrison) ¿no es así? – FunLovinCoder

+1

Puede hacerlo de tres maneras. # 1, almacene los datos en la base de datos y pase el 'pk' de la nueva entrada cuando los redireccione. # 2, almacena los datos en el backend 'cache', y pasa la clave nuevamente. # 3, guárdalo en la sesión. Cualquiera de estos es perfectamente normal para una aplicación web, incluso si es temporal. Si los datos del formulario no son triviales para analizar, también acelerarían el sistema si la salida ya estuviera en la memoria caché. –

14

Necesita usar un HTTP 1.1 Temporary Redirect (307).

Desafortunadamente, Django redirect() y HTTPResponseRedirect (permanente) de vuelta Solamente un 301 o 302. Se tienen que aplicar por sí mismo:

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) 

Véase también la django.http module.

Editar:

en las últimas versiones de Django, cambiar iri_to_uri importación a:

from django.utils.encoding import iri_to_uri 
+0

Las versiones más nuevas de Django tienen un redireccionamiento permanente HttpResponsePermanentRedirect, pero no estoy seguro de si resuelve el problema original https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpResponsePermanentRedirect – JiminyCricket

+0

permanent is 301, Entonces, no. – Lloeki

1

Simplemente llame a su nuevo punto de vista de su edad visual usando el mismo objeto de solicitud. Por supuesto, no dará como resultado una redirección como tal, pero si todo lo que le importa es 'transferir' datos de una vista a la otra, entonces debería funcionar.
He probado el siguiente fragmento y funciona.

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 
+0

Estaba usando esta solución y estaba funcionando sin problemas. – guival

0

Puede utilizar render y contexto con con él:

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

Puede recive VARs en plantilla:

{% If var name %} 
{{ var name }} 
{% endif %} 
5

uso requests paquete.Es muy fácil de poner en práctica

pip install requests 

continuación, puede llamar a cualquier URL con los datos de los métodos y transferencia

en sus puntos de vista importar solicitudes

import requests 

para enviar datos, siga el formato

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

para obtener la URL absoluta en django view, use

request.build_absolute_uri(reverse('view_name'))

Así, el código de la vista django parece

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

donde r es el objeto de respuesta con status_code y content atributo. r.status_code da el código de estado (en caso de éxito será 200) y r.content da el cuerpo de la respuesta. Hay un método JSON (r.json()) que convertirá respuesta a formato JSON

requests

requests.post

Cuestiones relacionadas