Cuando leo el código django a veces, veo en algunas plantillas reverse()
. No estoy muy seguro de qué se trata, pero se usa junto con HttpResponseRedirect. ¿Cómo y cuándo se reverse()
supone que debe usarse?
Sería bueno que alguien respondiera con algunos ejemplos ...
url--> view name
. Pero a veces, como cuando se redirige, debe ir en la dirección inversa y darle a Django el nombre de una vista, y Django genera la URL adecuada. En otras palabras,view name --> url
. Es decir,reverse()
(es el reverso de la función url). Puede parecer más transparente simplemente llamarlo,generateUrlFromViewName
pero eso es demasiado largo y probablemente no lo suficientemente general: docs.djangoproject.com/en/dev/topics/http/urls/…Respuestas:
reverse()
El | Documentación de DjangoSupongamos que en tu
urls.py
has definido esto:En una plantilla, puede referirse a esta url como:
Esto se representará como:
Ahora diga que quiere hacer algo similar en su
views.py
- por ejemplo, está manejando alguna otra url (no/foo/
) en otra vista (nosome_view
) y desea redirigir al usuario a/foo/
(a menudo el caso en el envío exitoso del formulario).Podrías simplemente hacer:
Pero, ¿qué pasa si quieres cambiar la URL en el futuro? Tendría que actualizar su
urls.py
y todas las referencias a él en su código. Esto viola DRY (Don't Repeat Yourself) , toda la idea de editar solo un lugar, que es algo por lo que debe esforzarse.En cambio, puedes decir:
Esto busca en todas las URL definidas en su proyecto 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
name
atributo; si desea cambiar la url en sí o la vista a la que se refiere, puede hacerlo editando solo un lugar -urls.py
.fuente
{{ url 'url_name' }}
debe estar{% url url_name %}
en Django 1.4 o anterior. Esto cambiará en la próxima versión de Django (1.5) y luego debería estarlo{% url 'url_name' %}
. Los documentos de la etiqueta de plantilla de URL proporcionan buena información si se desplaza hacia abajo un poco hacia la sección "compatibilidad conurl_reverse
. La mejor manera de lidiar con este tipo de rarezas es negarse a usarlas.Esta es una vieja pregunta, pero aquí hay algo que podría ayudar a alguien.
De los documentos oficiales:
P.ej. en plantillas (etiqueta de URL)
P.ej. en código python (usando la
reverse
función)fuente
Las respuestas existentes hicieron un gran trabajo al explicar el qué de esta
reverse()
función en Django.Sin embargo, esperaba que mi respuesta arrojara una luz diferente sobre el por qué : por qué usar
reverse()
en lugar de otros enfoques más directos, posiblemente más pitónicos en el enlace de vista de plantilla, y cuáles son algunas razones legítimas para la popularidad de esta "redirección a través dereverse()
patrón "en la lógica de enrutamiento de Django.Un beneficio clave es la construcción inversa de una url, como han mencionado otros. Justo como usaría
{% url "profile" profile.id %}
para generar la url desde el archivo de configuración de url de su aplicación: por ejemplopath('<int:profile.id>/profile', views.profile, name="profile")
.Pero como lo ha señalado el OP, el uso de
reverse()
también se combina comúnmente con el uso deHttpResponseRedirect
. ¿Pero por qué?Considere lo siguiente
views.py
:Y nuestro mínimo
urls.py
:En la
vote()
función, el código en nuestroelse
bloque se usareverse
junto conHttpResponseRedirect
el siguiente patrón:En primer lugar, esto significa que no tenemos que codificar la URL (de acuerdo con el principio DRY) pero, lo que es más importante,
reverse()
proporciona una forma elegante de construir cadenas de URL al manejar valores desempaquetados de los argumentos (args=(question.id)
es manejado por URLConfig). Se supone quequestion
tiene un atributoid
que contiene el valor5
, la URL construida a partir dereverse()
entonces sería:En el código de enlace de vista de plantilla normal, usamos
HttpResponse()
orender()
como generalmente implican menos abstracción: una función de vista que devuelve una plantilla:Pero en muchos casos legítimos de redireccionamiento, generalmente nos importa construir la URL a partir de una lista de parámetros. Estos incluyen casos como:
POST
solicitudLa mayoría de estos implican alguna forma de redireccionamiento y una URL construida a través de un conjunto de parámetros. ¡Espero que esto se agregue al útil hilo de respuestas!
fuente
La función admite el principio seco: garantizar que no codifique las URL en toda 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.
Utilícelo
reverse()
para darle la url de una página, dada la ruta a la vista o el parámetro page_name de su url conf. Lo usaría en casos en los que no tiene sentido hacerlo en la plantilla con{% url 'my-page' %}
.Hay muchos lugares posibles donde podría usar esta funcionalidad. Un lugar que he encontrado que lo uso es al redirigir a los usuarios en una vista (a menudo después del procesamiento exitoso de un formulario):
return HttpResponseRedirect(reverse('thanks-we-got-your-form-page'))
También puede usarlo al escribir etiquetas de plantilla.
Otra vez que utilicé
reverse()
fue con el modelo de herencia. Tenía un ListView en un modelo principal, pero quería pasar de cualquiera de esos objetos principales al DetailView de su objeto secundario asociado. Adjunté unaget__child_url()
función al padre que identificaba la existencia de un hijo y devolvía la url de su DetailView usandoreverse()
.fuente
Hay un documento para eso
https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-resolution-of-urls
se puede usar para generar una URL para una vista determinada
La principal ventaja es que no codifica rutas de código en su código.
fuente
Las respuestas existentes son bastante claras. En caso de que no sepa por qué se llama
reverse
: toma la entrada de un nombre de url y da la url real, que es inversa a tener una url primero y luego darle un nombre.fuente
El reverse () se utiliza para adherir el principio DRYGO de django, es decir, si cambia la url en el futuro, puede hacer referencia a esa url usando reverse (urlname).
fuente