Pregunta Django: ¿cómo puedo identificar la vista de llamada desde una plantilla?


Version corta:

¿Existe una forma simple e integrada de identificar la vista de llamadas en una plantilla de Django, sin pasar variables de contexto adicionales?

Versión larga (original):

Una de mis aplicaciones de Django tiene varias vistas diferentes, cada una con su propio patrón de URL con nombre, que representan 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 .

Intenté configurar las vistas para pasar variables de contexto adicionales (por ejemplo, "nombre de vista") para identificar la vista de llamadas, y también intenté usar {% 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: Con respecto al comentario de que este es simplemente un caso de que no entiendo bien MVC, entiendo MVC, pero Django no es realmente un marco MVC. Creo que la forma en que mi aplicación está configurada es consistente con la visión de Django sobre MVC: las vistas describen cual los datos se presentan y las plantillas describen cómo los datos son presentados. 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 publica simplemente "No", sería la respuesta más correcta :)

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


32
2018-04-27 06:17


origen


Respuestas:


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.


16
2018-04-27 15:11



Desde Django 1.5, el url_name es accesible usando:

request.resolver_match.url_name

Antes de eso, puedes usar un Middleware para eso:

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

Luego agregué esto en MIDDLEWARE_CLASSES, y en las plantillas tengo esto:

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

considerando 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.


19
2018-01-10 11:24



Desde Django 1.5 puedes acceder a una instancia de ResolverMatch mediante request.resolver_match.

ResolverMatch le proporciona el nombre de la url resuelta, el espacio de nombres, etc.


2
2018-05-17 13:57



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 este 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.


1
2018-05-31 18:28



Esto suena como el ejemplo perfecto de una vista genérica que puede configurar.

Vea los siguientes recursos:

Estos enlaces deberían ayudarlo a simplificar sus vistas y sus plantillas en consecuencia.


1
2018-04-27 06:42



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 la plantilla accede al nombre de vista como

{{viewname}} 

y también puedes usar esto en las comparaciones.


0
2018-04-27 06:30



La mayoría de las vistas genéricas, si no todas, heredan ContextMixin que agrega un view variable de contexto que apunta a la instancia de Vista.


0
2018-06-02 07:16



Si su nombre es consistente en su urls.py y views.py, que debería ser, entonces esto devolverá el nombre de la vista:

{{ request.resolver_match.url_name }}

Asegúrese de aplicarle contexto cuando lo llame en la plantilla. Por ejemplo, lo uso aquí para eliminar el botón Eliminar de mi vista de detalles, ¡pero en mi vista de actualización aún aparecerá el botón Eliminar!

{% if request.resolver_match.url_name != 'employee_detail' %}

0
2017-07-01 00:32



¿Por qué no intenta configurar una cookie de sesión y luego lee 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


-1
2018-04-27 06:39