Estoy construyendo una página html en Django, que tiene la siguiente estructura:
{% extends 'main/base_template.html' %} {% load filters %} {% block main_window %} <main class="col-md-9 ms-sm-auto col-lg-10 px-md-4"> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> <h1 class="h2">Stuff</h1> </div> <div class="row mb-3"> <div class="col-12 col-md-6"> {% include 'main/stuff/stuff_A.html' %} </div> <div class="col-12 col-md-6"> {% include 'main/stuff/stuff_B.html' %} </div> </div> <div class="row mb-3"> <div class="col-12 col-md-6"> {% include 'main/stuff/stuff_C.html' %} </div> <div class="col-12 col-md-6"> {% include 'main/stuff/stuff_D.html' %} </div> </div> {% endblock %}Y cada uno de los archivos html stuff_X tiene la misma estructura, por ejemplo:
<div class="row mb-3"> <div class="table-responsive"> <table class="table table-striped table-sm caption-top" style="width:40em"> <caption>Data</caption> <thead> <tr> <th scope="col">Data1</th> <th scope="col">Data2</th> <th scope="col">Data3</th> </tr> </thead> <tbody> <tr> <td id="stuff_a_data1" style="width:5em">{{ stuff_a.data1 }}</td> <td id="stuff_a_data2" style="width:5em">{{ stuff_a.data2 }}</td> <td id="stuff_a_data3" style="width:5em">{{ stuff_a.data2 }}</td> </tr> </tbody> </table> </div> </div>Entonces, las únicas cosas que realmente cambian son algunas identificaciones y el nombre de los datos que se recuperarán del contexto de Django.
¿Hay algún mecanismo que me permita escribir páginas genéricas para casos como este? Porque actualmente estoy manejando 4 (casi) páginas idénticas, agregando fragmentos de código en cada una de ellas cuando necesito modificar algo.
¡Gracias por adelantado!
Creo que puedes generalizar {{ stuff_a.data1 }} a {{ foo.data1}} usando
{% with stuff_a as foo, 'stuff_a' as foo_id_tag %} {% include 'main/stuff/foo.html' %} {% endwith %} siempre que las plantillas sean, de hecho, idénticas en forma o lo suficientemente similares como para que pueda dirigirlas con {%if ... %} . (Los identificadores se convertirían en id="{{foo_id_tag}}_data1" etc.)
La otra forma, que no es difícil, es usar format_html en su código python para generar cosas que luego pasa a la plantilla a través del contexto. O use una propiedad en el modelo relevante. Algo como
class Foo ( models.Model): ... @property def bar (self): bar = max( self.a*3 - self.b, 0 ) return f"{bar:.4}" por lo que puede hacer referencia a {{foo.bar}} en su plantilla, que no puede hacer ni siquiera aritmética trivial en los campos de foo.
Editar: había olvidado que with la funcionalidad se ha integrado en %include desde Django 1.algo. Entonces, más elegantemente,
{% include 'main/stuff/foo.html' with foo = stuff_a, foo_id_tag = 'stuff_a' %}No estoy seguro de si eso es lo que necesita, pero debería poder concatenar cadenas con el filtro de plantilla de adición :
{% with 'main/stuff/stuff_'|add:your_variable|add:'.html' as filename %} {% include filename %} {% endwith %} Necesitarás pasar your_variable desde tus views.py, obviamente.