2009-04-27 8 views
30

versión corta:Django: ¿Cómo puedo identificar la vista de llamada desde una plantilla?

¿Hay una manera sencilla, una función de identificar el punto de vista de llamadas en una plantilla de Django, sin pasar variables de contexto adicionales?

largo (original) Versión:

Una de mis aplicaciones Django tiene varios puntos de vista diferentes, cada uno con su propio patrón de URL llamado, que todos rinden la misma plantilla. Hay una cantidad muy pequeña de código de plantilla que debe cambiar dependiendo de la vista llamada, demasiado pequeña para que valga la pena configurar la creación de plantillas separadas para cada vista, así que idealmente necesito encontrar una manera de identificar la vista de llamada en la plantilla .

He intentado configurar las vistas para pasar variables de contexto adicionales (por ejemplo, "view_name") para identificar la vista de llamadas, y también he intentado utilizar {% ifequal request.path "/some/path/" %} comparaciones, pero ninguna de estas soluciones parece particularmente elegante. ¿Hay una mejor manera de identificar la vista de llamada desde la plantilla? ¿Hay alguna forma de acceder al nombre de la vista o al nombre del patrón de URL?


Actualización 1: En cuanto al comentario de que esto es simplemente un caso de Malentendiéndome MVC, entiendo MVC, pero Django's not really an MVC framework. Creo que la forma en que está configurada mi aplicación es coherente con la visión de Django sobre MVC: las vistas describen que se presentan los datos, y las plantillas describen cómo se presentan los datos. Simplemente sucede que tengo varias vistas que preparan datos diferentes, pero todas usan la misma plantilla porque los datos se presentan de la misma manera para todas las vistas. Solo busco una manera simple de identificar la vista de llamada desde la plantilla, si esto existe.

Actualización 2: Gracias por todas las respuestas. Creo que la pregunta está siendo sobreexigida, como mencioné en mi pregunta original, ya he considerado y probado todas las soluciones sugeridas, así que la he reducido a una "versión corta" ahora en la parte superior de la pregunta . Y en este momento parece que si alguien publicara simplemente "No", sería la respuesta más correcta :)

Actualización 3: Carl Meyer publicó "No" :) Gracias de nuevo, a todos.

+0

No estoy seguro de si puedo pensar en una razón por la cual diferentes vistas deberían estar llamando a la misma plantilla? ¿Puedes elaborar? Creo que es posible que hayas malentendido el concepto de MVC – Mez

+0

Gracias por el comentario. Cada una de las vistas realiza una consulta ORM diferente, pero todas las salidas tienen el mismo formato, de ahí la plantilla común por el bien de DRY. He editado la pregunta con más detalles. – bryan

+2

Me gustaría pasar una variable de contexto adicional a la plantilla. Solución simple y fácil de usar. Por qué no? – codeape

Respuesta

15

No, y sería una mala idea. Para hacer referencia directamente a una vista, el nombre de la función de la plantilla introduce un acoplamiento excesivamente estrecho entre la capa de visualización y la capa de la plantilla.

Una solución mucho mejor aquí es el sistema de herencia de plantillas de Django. Defina una plantilla principal común, con un bloque para el área (pequeña) que debe cambiar en la versión de cada vista. Luego, defina la plantilla de cada vista para que se extienda desde el elemento principal y defina ese bloque de manera apropiada.

+0

Gracias, Carl. Como mencioné en mi pregunta original, quería evitar la creación de más plantillas ya que las diferencias de plantilla son mínimas, pero este método tiene más sentido. – bryan

+0

En realidad, estaba pensando en agregar la clase css al elemento de contenido basado en el nombre de la vista, pero es posible que tenga razón con respecto al acoplamiento. –

0

una solución simple es:

def view1(req): 
    viewname = "view1" 
    and pass this viewname to the template context 

def view2(req): 
    viewname = "view2" 
    and pass this viewname to the template context 

en el acceso plantilla de la nombredevista como

{{viewname}} 

y también se puede utilizar esto en las comparaciones.

+1

Gracias por la respuesta, pero como se mencionó en la pregunta original, ya lo he intentado y estoy buscando una mejor manera, si existe. – bryan

-1

Por qué no intentar configurar una cookie de sesión, luego leer la cookie de su plantilla.

en sus puntos de vista establecer cookies

def view1(request): 
... 
#set cookie 
request.session["param"]="view1" 

def view2(request): 
    request.session["param"]="view2" 


then in your ONE template check something like.. 

{% ifequal request.session.param "view1" %} 
    ... do stuff related to view1 
{% endifequal %} 

{% ifequal request.session.param "view2" %} 
    ... do stuff related to "view2" 
{% endifequal %} 

Gath

+9

Gracias, pero estoy buscando reducir la complejidad, no aumentarla :) – bryan

1

Esto suena como el ejemplo perfecto de una visión genérica que se puede configurar.

consulte los siguientes recursos:

Estos enlaces deben ayudar a simplificar sus puntos de vista y sus plantillas en consecuencia.

+0

Gracias, pero mis puntos de vista ya están extendiendo las vistas genéricas. ¿O está sugiriendo que escriba mis propios puntos de vista genéricos? – bryan

+0

Por ejemplo, http://www.djangobook.com/es/2.0/chapter11/#cn41, 'extra_context' se pasa a la plantilla. Esta debería ser una solución simple a su problema. Defina una función, o use métodos integrados para pasar los datos en su 'contexto adicional' para que pueda compararlos dentro de su plantilla. –

+1

Gracias, pero como mencioné en mi pregunta original, ya lo he intentado, y sí, sé que funciona. Simplemente parece que debería haber una mejor manera de hacerlo. Supongo que mi pregunta se reduce a: ¿hay una forma incorporada de acceder a la vista de llamadas desde una plantilla? – bryan

1

Estoy trabajando en esto para un sistema de página de ayuda donde quería que cada vista se correspondiera con una página de ayuda en mi cms con una página predeterminada que se muestra si no se definió ninguna página de ayuda para esa vista. Me encontré con this blog donde usan un procesador de contexto de plantilla y algunos python inspeccionan la magia para deducir el nombre de la vista y poblar el contexto con él.

19

Desde Django 1.5, el url_name es accesible usando:

request.resolver_match.url_name 

Antes de eso, se puede utilizar un middleware para ello:

from django.core.urlresolvers import resolve 

class ViewNameMiddleware(object): 
    def process_view(self, request, view_func, view_args, view_kwargs): 
     url_name = resolve(request.path).url_name 
     request.url_name = url_name 

A continuación, añadir esta en MIDDLEWARE_CLASSES, como en las plantillas que tienen esto:

{% if request.url_name == "url_name" %} ... {% endif %} 

teniendo en cuenta que RequestContext (solicitud) siempre se pasa a la función de renderizado Prefiero usar url_name para urls, pero uno puede usar resolve(). App_name y resolve(). Func.name, pero esto no funciona con decoradores: en su lugar, se devuelve el nombre de la función del decorador.

+0

en realidad este middleware no es necesario ya que la solicitud ya proporciona el URL resuelto url_name => request.resolver_match.url_name –

+5

Gracias por la nota. En realidad, 'request.resolver_match' se introdujo en Django 1.5 en 2013, mientras que la publicación es de 2012. Debe haber una bandera para 'Obsoleto' en StackOverflow :) – Tisho

+1

Para usar' request.resolver_match.url_name' en templates 'django. core.context_processors.request' se debe agregar a la configuración 'TEMPLATE_CONTEXT_PROCESSORS'. – juliocesar

1

Desde Django 1.5 puede acceder a una instancia de ResolverMatch hasta request.resolver_match.

El ResolverMatch le da el nombre resuelto url, espacio de nombres, etc.

+0

¡Gracias, estaba buscando el 'view_name' identificado! – tbolender

0

La mayoría de las vistas genéricas - si no todos - hereda el ContextMixin que añade una variable view contexto que apunta a la instancia de vista.

Cuestiones relacionadas