2011-04-10 20 views
18

Estoy intentando que mi formulario se envíe a una ruta que validará los datos y luego se redireccionará a la ruta original.¿Cómo puedo redireccionar después de POST en Pyramid?

Por ejemplo: carga

  • usuario la página website.com/post
  • Mensajes formar los datos a website.com/post-save~~V~~plural~~3rd
  • usuario se redirige a website.com/post

Pyramid me está causando algunos problemas al hacer esto.

Aquí es mi adelgazado views.py

def _get_link_form(post_data): 
    """ Returns the initialised form object """ 

    return LinkForm(post_data) 

def home_page(request): 

    form = _get_link_form(request.POST) 
    return {'form' : form} 

def save_post(request): 
    """ form data is submitted here """" 

    form = _get_link_form(request.POST) 

    if not form.validate(): 
     return home_page(request, form) 

Este es el código que he estado jugando con. No solo no funciona, también se siente desordenado y hackeado. Seguramente hay una forma más simple de 'redirigir después de POST' en Pyramid?

Respuesta

8

La documentación de la pirámide tiene una particular sobre puntos section con el siguiente ejemplo:

from pyramid.httpexceptions import HTTPFound 

def myview(request): 
    return HTTPFound(location='http://example.com') 
+0

de redireccionamiento es fácil. El problema es, ¿cómo redirecciono a 'home_page' y envío los errores de formulario encontrados en' save_post'? – dave

+0

Una forma de lidiar con esto es invertir la forma en que está haciendo las cosas ahora: haga que 'home_page' también sea la vista a la que se envía el formulario, y luego redirija solo si el envío fue exitoso. Entonces, si necesita mostrar errores, 'home_page' ya tiene el objeto de formulario que necesita. –

+0

Estaba considerando eso, pero tengo dos callables de vista diferentes que mostrarán el formulario. Podría pedirles a los dos que se presenten en la vista principal, invocable (home_page, en este ejemplo), pero sería bueno que cada vista invocable pudiera redirigirse a sí misma después de enviarla, si eso tiene sentido ... – dave

0

Asumiendo que su página de inicio es la vista predeterminada de su aplicación web pirámide, que puede hacer:

def _get_link_form(post_data): 
    """ Returns the initialised form object """ 

    return LinkForm(post_data) 

def home_page(request): 

    form = _get_link_form(request.POST) 
    return {'form' : form} 

def save_post(request): 
    form = _get_link_form(request.POST) 

    if not form.validate(): 
     from pyramid.httpexceptions import HTTPFound 
     return HTTPFound(location=request.application_url) 

Básicamente, necesita saber cómo se "agregó" la vista de página principal a su Configurador. Si su página de inicio en realidad vive en/pocos/niveles/profundidad/sitio web, una redirección podría tener este aspecto:

 return HTTPFound(location=request.application_url + '/few/levels/deep/homepage') 
+0

Hola Rocky, gracias por el complemento jinja2. –

+0

El uso de 'HTTPFound' da como resultado el código de respuesta HTTP 302, por lo que la siguiente solicitud será GET en lugar de la POST original. Como consecuencia, no obtendrá los datos del formulario en la vista 'home_page' porque está buscando en' request.POST'. –

26

Su problema se resuelve más fácilmente con sólo anuncio a la misma URL que el formulario se muestra en, y simplemente redireccionando al usuario fuera de la página cuando el POST es exitoso. De esta forma, hasta que el formulario se envíe correctamente, no cambiará las URL.

Si solo desea enviar por correo a una URL diferente, debe guardar los datos mediante las sesiones, ya que obviamente maneja los datos del formulario entre las solicitudes.

Normalmente, si desea controlar los errores en sus formularios, debe utilizar una sesión y mensajes flash. Para hacerlo, simplemente agregue una ubicación para que aparezcan los mensajes flash en su plantilla base y soporte para la sesión de configuración usando algo como pyramid_beaker.

Asumiendo que su página de inicio es de configuración en la 'casa' nombre-ruta:

from pyramid.httpexceptions import HTTPFound 

def myview(request): 
    user = '<default user field value>' 
    if 'submit' in request.POST: 
     user = request.POST.get('user') 
     # validate your form data 
     if <form validates successfully>: 
      request.session.flash('Form was submitted successfully.') 

      url = request.route_url('home') 
      return HTTPFound(location=url) 
    return { 
     # globals for rendering your form 
     'user': user, 
    } 

Note como si la forma no puede validar utiliza el mismo código que hizo para hacer que la forma original, y sólo si es exitoso redirigir Este formato también puede manejar rellenar el formulario con los valores utilizados en el envío y los valores predeterminados.

Puede recorrer los mensajes flash en su plantilla de elección usando request.session.peek_flash() y request.session.pop_flash().

route_url admite la mutación de la cadena de consulta en la url generada también, si desea marcar la vista de página de inicio para verificar los datos de la sesión.

Obviamente puede simplemente pasar todo lo que está en la cadena de consulta a la página de inicio, pero esa es una vulnerabilidad de seguridad bastante grande que las sesiones pueden ayudar a proteger.

0

hago esto así:

from pyramid.httpexceptions import HTTPCreated 

response = HTTPCreated() 
response.location = self.request.resource_url(newResource) 
return response 

Esto envía el código HTTP Creado, 201

0

una manera limpia está utilizando la "sobrecarga" proporcionado por la pirámide para diferentes tipos de peticiones, ejemplo por, que se puede decorar sus métodos de esta manera:

@action(request_method='GET', 
     renderer='mypackage:/templates/save.mako', 
     name='save') 
def save(request): 
    ''' Fill the template with default values or leave it blank''' 
    return {} 


@action(request_method='POST', 
     renderer='mypackage:/templates/save.mako', 
     name='save') 
def save_post(request): 
    """ form data is submitted here """" 
    # process form 

En el HTML, debe llamar a la forma de acción, como

<form method="POST" id="tform" action="${request.route_url('home', action='save')}">

De esta manera, un método se procesa cuando se utiliza el método POST, y el otro cuando se utiliza el GET. El mismo nombre , pero dos implementaciones.

+0

Claro, pero en la rama POST, cuando la validación falla, generalmente debe hacer lo que hace en GET ... – pihentagy

+0

No hay un decorador 'action' en Pyramid. Supongo que estás usando el decorador ['action'] (http://pyramid-handlers.readthedocs.org/en/latest/api.html#pyramid_handlers.action) del paquete * pyramid_handlers *. –

+0

Creo que no entendió el punto de la pregunta que era enviar un formulario usando POST a una url ** diferente ** luego la utilizada para OBTENER el formulario. Ambos manejadores están registrados con el mismo nombre ('save') por lo que se puede acceder bajo la misma URL. –

0

La documentación pirámide tiene contenido sobre redirección, se puede ver más información en el enlace de abajo:

Pyramid documentation

import pyramid.httpexceptions as exc 
raise exc.HTTPFound(request.route_url("section1")) # Redirect 
Cuestiones relacionadas