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 de reverse()
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 ejemplo path('<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 de HttpResponseRedirect
. ¿Pero por qué?
No estoy muy seguro de qué se trata, pero se usa junto con HttpResponseRedirect. ¿Cómo y cuándo se supone que se usa este reverse ()?
Considere lo siguiente views.py
:
from django.http import HttpResponseRedirect
from django.urls import reverse
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected = question.choice_set.get(pk=request.POST['choice'])
except KeyError:
# handle exception
pass
else:
selected.votes += 1
selected.save()
return HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
))
Y nuestro mínimo urls.py
:
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('<int:question_id>/results/', views.results, name='polls-results'),
path('<int:question_id>/vote/', views.vote, name='polls-vote')
]
En la vote()
función, el código en nuestro else
bloque se usa reverse
junto con HttpResponseRedirect
el siguiente patrón:
HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
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 que question
tiene un atributo id
que contiene el valor 5
, la URL construida a partir de reverse()
entonces sería:
'/polls/5/results/'
En el código de enlace de vista de plantilla normal, usamos HttpResponse()
o render()
como generalmente implican menos abstracción: una función de vista que devuelve una plantilla:
def index(request):
return render(request, 'polls/index.html')
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:
- Envío de formulario HTML mediante
POST
solicitud
- Inicio de sesión de usuario posterior a la validación
- Restablecer contraseña a través de tokens web JSON
La 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!
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/…