2012-06-28 7 views
133

Cuando leo código django a veces, veo en algunas plantillas reverse(). No estoy seguro de qué es esto, pero se usa junto con HttpResponseRedirect. ¿Cómo y cuándo se supone que se utilizará este reverse()?¿Qué es el reverso() en Django

Sería bueno que alguien le dio una respuesta con algunos ejemplos ...

+2

Dado un patrón de URL, Django usa url() para recoger la opinión de la derecha y generar una página. Es decir, 'url -> ver nombre'. Pero a veces, como al redirigir, necesitas ir en la dirección opuesta y darle a Django el nombre de una vista, y Django genera la url apropiada. En otras palabras, 'ver nombre -> url'. Es decir, 'reverse()' (es el reverso de la función url). Puede parecer más transparente simplemente llamarlo 'generateUrlFromViewName' pero es demasiado largo y probablemente no lo suficientemente general: https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-resolution-of-urls – neuronet

+0

@neuronet Gran explicación, gracias. Este nombre parecía (y parece) particularmente no intuitivo para mí, lo que considero un grave pecado. ¿Quién no odia la ofuscación innecesaria? –

Respuesta

215

https://docs.djangoproject.com/en/stable/ref/urlresolvers/#reverse

en su urls.py definir esto:

url(r'^foo$', some_view, name='url_name'), 

en una plantilla que se puede hacer referencia a esta URL como:

<!-- django <= 1.4 --> 
<a href="{% url url_name %}">link which calls some_view</a> 

<!-- django >= 1.5 or with {% load url from future %} in your template --> 
<a href="{% url 'url_name' %}">link which calls some_view</a> 

este será mostrado como

<a href="/foo/">link which calls some_view</a> 

ahora diga que desea hacer algo similar en su views.py - por ejemplo, usted está manejando alguna otra URL (no /foo/) en algún otro punto de vista (no some_view) y desea redirigir al usuario a /foo/ (a menudo el caso en el envío del formulario éxito)

usted podría hacer

return HttpResponseRedirect('/foo/') 

pero, ¿qué sucede si desea cambiar la URL en el futuro? Debería actualizar su urls.pyy todas las referencias en su código. Esto viola DRY (google it).

lugar se puede decir

from django.core.urlresolvers import reverse 
return HttpResponseRedirect(reverse('url_name')) 

Esto se ve a través de todas las URL definidas en el proyecto para la url definida con el nombre url_name y devuelve la URL real /foo/.

esto significa que se refiere a la url solo por su atributo name - si quiere cambiar la url misma o la vista a la que se refiere, puede hacerlo editando un solo lugar - urls.py. Esta idea de editar un solo lugar se denomina "No repetir" y es algo por lo que debemos esforzarnos.

+1

FYI, '{{url 'url_name'}}' debe ser '{% url url_name%}' en Django 1.4 o anterior. Esto cambiará en la próxima versión de Django (1.5) y debería ser '{% url 'url_name'%}'. Los documentos del [url templatetag] (https://docs.djangoproject.com/en/1.4/ref/templates/builtins/#url) ofrecen información útil si se desplaza un poco hacia abajo hasta la sección "compatibilidad con versiones anteriores" –

+0

j_syk gracias - he estado haciendo @load url desde future @ desde que salió 1.3 y olvidé que aún no es el predeterminado. Actualizaré mi respuesta para que no tropiece con los inexpertos. – scytale

+0

no es demasiado crítico, y para continuar con el tema de no tropezar con los inexpertos, pero debe ser etiquetas de bloqueo '{%%}' variables etiquetas '{{}}' para la etiqueta url :) –

0

El reverso() se utiliza para cumplir con el principio django DRY, es decir, si cambia la url en el futuro, entonces puede hacer referencia a esa url utilizando el reverso (urlname).

1

La función es compatible con el principio de secado, garantizando que no codifica las direcciones URL de su aplicación. Una URL debe definirse en un solo lugar, y solo en un lugar: su URL conf. Después de eso, solo estás haciendo referencia a esa información.

Utilice reverse() para darle la url de una página, dada la ruta a la vista, o el parámetro page_name de su configuración de url. Lo usaría en casos donde no tiene sentido hacerlo en la plantilla con {% url 'my-page' %}.

Hay muchos lugares posibles donde puede usar esta funcionalidad. Un lugar que he encontrado lo uso cuando es redirigir a los usuarios en una vista (a menudo después de que el procesamiento con éxito de un formulario) -

return HttpResponseRedirect(reverse('thanks-we-got-your-form-page'))

También puede utilizar para escribir etiquetas de plantilla.

Otra vez que utilicé reverse() fue con la herencia del modelo. Tenía un ListView en un modelo principal, pero quería acceder desde cualquiera de esos objetos principales al DetailView de su objeto hijo asociado. Adjunté una función get__child_url() al padre que identificó la existencia de un niño y devolvió la url de su DetailView usando reverse().

1

Demasiado vieja pregunta, pero esto podría ayudar a alguien

de los documentos oficiales

"Django proporciona herramientas para realizar el URL de marcha atrás que coinciden con los diferentes capas en las que se necesitan URL: En las plantillas: Uso de la URL etiqueta de plantilla. En código Python: Uso de la función reverse() En código de nivel superior relacionado con el manejo de URL de instancias de modelo Django: El método get_absolute_url() ".

Por ejemplo: en las plantillas (etiqueta del URL)

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a> 

Por ejemplo: en el código Python (función inversa)

return HttpResponseRedirect(reverse('news-year-archive', args=(year,))) 
Cuestiones relacionadas