2010-03-22 40 views
65

Tengo que construir una URL de forma dinámica de acuerdo con la URL actual. Usar la etiqueta {% url %} es la forma más fácil de hacerlo, pero necesito el nombre de la url actual para generar la nueva de forma dinámica.¿Cómo obtener el nombre de la url actual usando Django?

¿Cómo puedo obtener el nombre de la url adjunta al urlconf que conduce a la vista actual?

EDITAR: Sé que puedo manualmente hacer manualmente la url usando get_absolute_url pero prefiero evitarlo ya que es parte de una conferencia y me gustaría mostrar una sola forma de construir urls.

Los estudiantes saben cómo usar {% url %}. Ellos saben que enfrentan un problema cuando tienen que generar una URL más completa basada en la actual. La forma más fácil es usar {% url %} nuevamente, con algunas variaciones. Como hemos nombrado url, , necesitamos saber cómo obtener el nombre de la url que llamó a la vista actual.

EDIT 2: otro caso de uso es mostrar partes de la plantilla base de manera diferente según la plantilla base. Hay otras maneras de hacerlo (usando CSS y {% block%}, pero en algún momento es bueno poder eliminar la etiqueta de la entrada de menú de base.html si el nombre de vista coincide con el enlace.

+5

fui encontrando esta pregunta durante la búsqueda de una forma de salida de la url actual **, absoluta a través de una etiqueta de plantilla ** ... si lo que buscas es que, además, es: '{{petición .get_full_path}} ' – Dolph

Respuesta

85

No sé cuánto tiempo esta característica ha sido parte de Django, pero como muestra el following article, se puede lograr de la siguiente manera en la vista:

from django.core.urlresolvers import resolve 
    current_url = resolve(request.path_info).url_name 

Si necesita que en cada plantilla, la escritura una solicitud de plantilla puede ser apropiada.

Editar: la aplicación de nuevas DJANGO ACTUALIZACIÓN

Siguiendo la corriente actualización Django:

Django 1,10 (link)

Importing from the django.core.urlresolvers module is deprecated in favor of its new location, django.urls

Django 2,0 (link)

The django.core.urlresolvers module is removed in favor of its new location, django.urls .

Por lo tanto, la forma correcta de hacerlo es la siguiente:

from django.urls import resolve 
current_url = resolve(request.path_info).url_name 
+0

¿Por qué? Por lo que he entendido su pregunta, una parte vital de esto fue cómo lograrlo "Desde que hemos nombrado la url, necesitamos saber cómo obtener el nombre de la url que llamó a la vista actual." ... –

+1

En realidad lukas estaba gruñón ese día y descarté tu respuesta completamente arbitrariamente. Me disculpo, porque esta es realmente la respuesta correcta. Voy a editarlo para que sea más simple. –

+8

'resolve()' no se puede resolver si le pasa una cadena de consulta y simplemente levanta un 404. 'get_full_path()' devuelve la ruta y la cadena de consulta. Deberá usar 'resolve (request.path_info)'. –

1

+0

+1 Esto no responde a la pregunta, pero resuelve un problema planteado en ella. –

0

es un poco claro en su pregunta, pero http://docs.djangoproject.com/en/dev/topics/http/urls/ probablemente proporcionará una explicación a lo que está buscando

Especialmente útil observar cómo procesa Django solicitudes:.

Cuando un usuario solicita una página de su Sitio con Django, este es el algoritmo que sigue el sistema para determinar qué bacalao Python e para ejecutar:

  1. Django determina el módulo raíz URLconf que se utilizará. Normalmente, este es el valor de la configuración ROOT_URLCONF, pero si el objeto HttpRequest entrante tiene un atributo llamado urlconf (establecido por el proceso de solicitud de middleware), su valor se usará en lugar de la configuración ROOT_URLCONF.
  2. Django carga ese módulo de Python y busca la variable urlpatterns. Esta debería ser una lista de Python, en el formato devuelto por la función django.conf.urls.defaults.patterns().
  3. Django recorre cada patrón de URL, en orden, y se detiene en el primero que coincide con la URL solicitada.
  4. Una vez que una de las expresiones regulares coincide, Django importa y llama a la vista dada, que es una función simple de Python. La vista obtiene una HttpRequest como su primer argumento y cualquier valor capturado en la expresión regular como argumentos restantes.

Si usted es justo después de la ruta completa, puede intentar:

http://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.get_full_path

Espero que ayude - indica cómo utilizar el módulo URLconf, y se espera que ayudarle a usted en la dirección correcta.

+0

Gracias, pero sé que :-) Agregué algunas explicaciones para evitar malentendidos. –

3

Aclaración de la pregunta: "En una vista, ¿cómo se obtiene el nombre de un urlpattern que lo señala, suponiendo que exista exactamente un tal urlpattern?"

Esto puede ser deseable por las razones indicadas:. Desde la vista, queremos una vía seca de conseguir una URL a la misma vista (que no quiere tener que conocer nuestro propio nombre URLPATTERN)

respuesta corta: en realidad no es lo suficientemente simple para enseñar a su clase, pero que podría ser una cosa de la diversión para que usted pueda hacer en una hora o dos y vomita en GitHub

Si realmente quería hacer esto, usted. Tendría que crear una subclase RegexURLResolver y modificar el método de resolución para devolver el patrón coincidente (del que puede obtener el nombre del patrón) en lugar de los pares de palabras clave y valores http://code.djangoproject.com/browser/django/trunk/django/core/urlresolvers.py#L142

Puede crear un decorador o quizás un middleware más apropiado que use esta subclase para obtener el nombre del patrón y almacenar ese valor en algún lugar de la solicitud para que las vistas puedan usarlo.

Si realmente desea hacer eso y se encuentra con algún problema, hágamelo saber y probablemente pueda ayudarlo.

Para su clase, simplemente les pediría que codifiquen el nombre del patrón en la vista o la plantilla. Creo que esta es la forma aceptable de hacerlo.

Actualización: Cuanto más pienso en ello, más me desanimaría a tratar de conseguir un nombre URLPATTERN en una vista. Los parámetros de urlpattern son bastante independientes de los parámetros de la vista a la que apuntan. Si desea apuntar a una determinada url, necesita saber cómo funciona el urlpattern, no solo cómo funciona la vista. Si necesita saber cómo funciona el urlpattern, también debería saber el nombre del urlpattern.

91

A partir del 1 de Django.5, este se puede acceder desde el objeto solicitud

current_url = request.resolver_match.url_name 

https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.resolver_match

+0

Cuando lo puse en un procesador de contexto, funcionó, pero este extraño error se mostró en la consola: 'AttributeError: 'WSGIRequest' no tiene atributo 'resolver_match'' – fjsj

+1

El' resolver_match 'se agrega solo al objeto de solicitud después de llamar a todos los middleware de solicitud. Ahí es cuando las urls se están resolviendo. De modo que solo puede acceder desde view middleware en adelante. (funciones process_view de middleware). No estará disponible en las funciones de middleware de solicitud. (funciones de solicitud de proceso de middleware). – Bharathwaaj

+2

Sí, pero este error ocurre en un procesador de contexto de plantilla. – fjsj

7

Esto puede lograrse a través de:

request.resolver_match.url_name 

Django> 1,8

15

Para los que los espacios de nombres de su url patrones, entonces puede estar interesado en el nombre de la url en el espacio de nombre de la solicitud. En este caso, Django lo llamó view_name en su lugar.

request.resolver_match.view_name 

# return: <namespace>:<url name> 
+0

Gracias, pero esto es más o menos una de las respuestas anteriores de @ dariusz-niespodziany, ¿no? http://stackoverflow.com/a/31931833/1450294 –

+4

Si no usó el espacio de nombres 'urls.py' entonces @ dariusz-niespodziany es inmediatamente' reverse'-able. Pero si está usando el espacio de nombres, 'resolver_match.url_name' no está directamente' reverse'-able. Por lo tanto, debe agregar el espacio de nombres usted mismo. Entonces, en vez de hacerlo usted mismo, Django ya estableció el ['.view_name'] (https://github.com/django/django/blob/1.10.6/django/urls/resolvers.py#L51) al momento de la inicialización. – Yeo

Cuestiones relacionadas