2010-07-09 32 views
54

en mi función de vista Quiero llamar a otro punto de vista y pasar los datos a la misma:Django redirección de retorno() con parámetros

return redirect('some-view-name', backend, form.cleaned_data) 

, donde backend es de registration.backends objeto y form.cleaned_data es un diccionario de los datos del formulario (pero ambos deben enviarse como * args o ** kwargs para evitar el error Don't mix *args and **kwargs in call to reverse()!). De lo que he encontrado en la documentación:

def my_view(request): 
    ... 
    return redirect('some-view-name', foo='bar') 

Parece que necesito proporcionar 'un poco de nombre-vista-argumento, pero es sólo el nombre de la función de vista, o el nombre de la URL ? Así que me gustaría para que sea similar a la forma en que se hace en django-registro, donde:

to, args, kwargs = backend.post_registration_redirect(request, new_user) 
return redirect(to, *args, **kwargs) 

def post_registration_redirect(self, request, user): 
    return ('registration_complete',(), {}) 

Ok por lo que ahora, puedo llamar directamente a mi función de vista o tengo que proporcionar una dirección URL para ello? Y, lo que es más importante, ¿cómo se verá mi llamada de funciotn (y una URL si es necesario)? Tanto el backend como los clean_data se pasan a través de esta vista para un uso posterior. He intentado esto, pero es inadecuada:

url(r'^link/$', some-view-name) 
def some-view-name(request, *args): 

Así como esto:

return redirect('some_url', backend=backend, dataform.cleaned_data) 
url(r'^link/$', some-view-name)  
def some-view-name(request, backend, data): 

todavía NoReverseMatch. Pero en django-registration, he visto algo como esto:

url(r'^register/$',register,{'backend': 'registration.backends.default.DefaultBackend'}, name='registration_register'), 

def register(request, backend, success_url=None, form_class=None, 
      disallowed_url='registration_disallowed', 
      template_name='user/login_logout_register/registration_form.html', 
      extra_context=None): 

Respuesta

52

Primero, su definición de URL no acepta ningún parámetro. Si desea que los parámetros pasen de la URL a la vista, debe definirlos en urlconf.

En segundo lugar, no está del todo claro qué es lo que espera que suceda con el diccionario de clean_data. No olvides que no puedes redireccionar a un POST, esto es una limitación de HTTP, no de Django, por lo que tu clean_data necesita ser un parámetro de URL (horrible) o, ligeramente mejor, una serie de parámetros GET, por lo que la URL sería en la forma:

/link/mybackend/?field1=value1&field2=value2&field3=value3 

y así sucesivamente. En este caso, field1, field2 y field3 son no incluidos en la definición de URLconf; están disponibles en la vista a través del request.GET.

Así que su URLconf sería:

url(r'^link/(?P<backend>\w+?)/$', my_function) 

y la vista se vería así:

def my_function(request, backend): 
    data = request.GET 

y lo contrario sería (después de importar urllib):

return "%s?%s" % (redirect('my_function', args=(backend,)), 
        urllib.urlencode(form.cleaned_data)) 

Editado después del comentario

El objetivo de usar redirección e inversión, como lo ha estado haciendo, es que vaya a la URL, devuelve un código Http que hace que el navegador redireccione a la nueva URL y la llame.

Si simplemente desea llamar a la vista desde dentro de su código, simplemente hágalo directamente, sin necesidad de utilizar el comando reverse.

Dicho esto, si todo lo que quiere hacer es almacenar los datos, a continuación, sólo hay que poner en la sesión:

request.session['temp_data'] = form.cleaned_data 
+0

y si no voy a operar en datos_limpios en esta vista, ¿pero solo pasarlo para un uso posterior? Tengo muchos campos en el dict clean_data, así que me gustaría evitar pasarlos como una cadena get :) – muntu

+0

No entiendo este comentario. Explique con más detalle, actualizando su pregunta si es necesario. –

+0

esta segunda vista solo almacenará estos datos enviados para su uso posterior. Pero, ¿estás seguro de que necesito proporcionar la URL? Desde documentos, parece que solo estoy llamando a la vista directamente. También esperaba simplemente enviar un diccionario con backend y datos en redirect() (como se hace en django-registration) y luego en la url (como esta función dict en el registro), pero por lo que veo es imposible? – muntu

29

urls.py:

#...  
url(r'element/update/(?P<pk>\d+)/$', 'element.views.element_update', name='element_update'), 

views.py:

from django.shortcuts import redirect 
from .models import Element 


def element_info(request): 
    # ... 
    element = Element.object.get(pk=1) 
    return redirect('element_update', pk=element.id) 

def element_update(request, pk) 
    # ... 
Cuestiones relacionadas