Pregunta

Tengo un proyecto django pro1 con varias aplicaciones: app1, app2, app3, etc. Quiero mostrar una plantilla de nivel superior que contenga bloques de todas y cada una de las aplicaciones:

example_base_template.html:

[header /]
[left nav bar]{{ app1 rendered template }}[/left nav bar]
[right nav bar]{{ app2 rendered template }}[/right nav bar]
[center section]{{ app1 main functionality template }}[/center section]
[footer]{{ app3 rendered template }}{{ app4 rendered template }}[/footer]

Todas esas plantillas de aplicaciones son dinámicas, que usan DB. ¿Cómo hacer eso de la manera más adecuada y elegante? ¿O tal vez la pregunta es cómo conectar 4 vistas diferentes a una URL?

¿Fue útil?

Solución

Tuvimos un problema similar a este y la clave es obtener los datos correctos en el contexto. Lo que hicimos fue dividir la creación de datos / Relleno de contexto para cada vista en una rutina separada para construir el contexto. Las vistas originales simplemente llaman a su rutina respectiva y luego representan su plantilla. La vista compuesta llama a cada uno de los creadores de contexto y luego representa la plantilla maestra, que luego incluye las sub-plantillas.

Aquí es donde nos encontramos con un pequeño problema con el sistema de plantillas Django. Estábamos almacenando en caché fragmentos de plantilla y algunos de estos fragmentos tomaron datos que era muy costoso generar. Si el fragmento no estaba rancio, definitivamente no queríamos hacer el trabajo. Pero retrasar el trabajo hasta que supimos que lo necesitábamos significaba que ahora estábamos en la plantilla y:

  • No puede pasar parámetros a métodos desde una plantilla.
  • El método django.template .__ init __. Variable._resolve_lookup () se rompió porque si pasaba un invocable, ¡no lo llamaría! Si hace referencia a un método de un objeto en el contexto, eso funciona bien.

La razón por la que se necesitan callables para trabajar es que le permite pasar una función currificada, es decir, una función que ya tiene algunos (o todos) sus parámetros especificados, pero que aún no se ha llamado. Por lo tanto, la vista (o la construcción del contexto en el caso) debería poder cursar una función completamente especificada (recuerde, no puede pasar parámetros en las plantillas mismas) para que la plantilla cuando sea necesario podría invocar al invocable, obtener los datos y listo.

Tomamos dos enfoques separados para esto:

Desde que hicimos este sitio, he aprendido que podríamos haber podido resolverlo usando generadores como productores de datos retrasados. Los generadores actúan como una función curricular (en la que puede pasar parámetros arbitrarios para la configuración), pero el motor de plantillas los ve como solo otro iterador. Hay un gran tutorial sobre este tema. Nota: los generadores no son matrices y solo puede consumirlos una vez, por lo que es posible que sea necesario modificar parte de su lógica.

La próxima vez creo que simplemente iremos con plantillas jinja2 y dejaremos de fastidiar con las plantillas de Django .

Otros consejos

Puede usar un {% include%} etiqueta. Pero no te ayuda mucho. La mejor solución es escribir etiqueta de inclusión personalizada con plantilla y funcionalidad necesarias.

No puede (de manera simple) mezclar varias vistas en una. Pruebe con etiquetas su bonita solución django.

Hice esto escribiendo etiquetas de plantilla personalizadas para cada aplicación que quería incluir. Al principio, mis etiquetas de plantilla simplemente pasaron html codificado. Más tarde descubrí que las etiquetas podían cargar sus propios fragmentos de plantilla. También había un fragmento en alguna parte que era una última etiqueta genérica de contenido que funcionaba bastante bien.

Muchas aplicaciones reutilizables (especialmente las seleccionadas en el proyecto Pinax ) sirven como excelentes ejemplos sobre cómo usar la costumbre Etiquetas de plantilla para insertar contenido. La talk en DjangoCon 2008 también puede ayudar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top