Potenciando RML con Django#

Esta sección tiene el objetivo de brindarle suficiente información técnica para comprender la sintaxis del lenguaje del sistema de plantillas Django.

Ver también

¿Qué es Django?

Django es un framework gratuito y de código abierto basado en Python que sigue el patrón arquitectónico MVT (Model-View-Template). Se ejecuta del lado del servidor (back-end) y fomenta un desarrollo rápido con un diseño limpio y pragmático.

El sistema de plantillas de Django proporciona etiquetas que funcionan de manera similar a algunas construcciones de programación, como una etiqueta if para pruebas booleanas y una etiqueta for para bucles, entre otras. Sin embargo, estas etiquetas no se ejecutan directamente como el código Python correspondiente y el sistema de plantillas no ejecutará expresiones Python arbitrarias. De forma predeterminada, solo se admiten las etiquetas, los filtros y la sintaxis que se presentan en secciones posteriores (aunque se puede agregar extensiones propias al lenguaje de la plantilla).

Para más información consulte la documentación oficial de Django .

Importante

El siguiente contenido se explicará en base al siguiente ejemplo. Asegúrese de actualizar y modificar según sus necesidades.

También, tenga en cuenta consultar la documentación sobre formas en la aplicación web de Linkaform.

Ver formulario
../../_images/ejemplocompleto.png

Variables#

Las variables permiten almacenar y representar información. En las plantillas de Django, puede representar variables poniéndolas entre {{ }} corchetes:

1<story>
2    {{ variable }}
3<story>

Importante

El nombre de una variable debe seguir la convención snake_case.

Los dobles corchetes {{ }} se utilizan para llamar a la variable. Cualquier contenido dentro de los dobles corchetes se interpreta como una instrucción para obtener y mostrar el valor real de la expresión en ese punto de la plantilla.

Una variable utiliza el signo de porcentajes {% %} para definir bloques de control y lógica, como declaraciones condicionales, bucles y otras operaciones que no necesariamente generan contenido directamente para mostrar, sino que afectan la estructura y el flujo de la plantilla.

Para declarar una variable utilice la palabra reservada set seguido del valor que desea asignar. Por ejemplo:

1<story>
2    {% set valor = 5 %}
3
4    <para>{{ valor }}</para> <!-- Imprime 5 -->
5</story>

Template tags#

En las plantillas de Django, puede realizar lógica de programación. Sin embargo, Django tiene limitaciones; solo podrá ejecutar declaraciones if y bucles for.

Ver también

Las palabras reservadas if y for se denominan Template tags en Django.

Para ejecutar template tags, encierre entre corchetes {% %}.

Condicionales#

Una declaración if evalúa una variable y ejecuta un bloque de código si el valor es verdadero.

1<story>
2    {% if condition %}
3
4        ...
5
6    {% endif %}
7</story>

Nota

Utilice endif para cerrar la condición. Es obligatorio.

Utilice elif si la condición anterior no es verdadera.

 1<story>
 2    {% set variable1 = '' %}
 3    {% set flag = 2 %}
 4
 5    {% if flag == 1 %}
 6        {% set variable1 = 'El valor es 1' %}
 7        {% elif flag == 2 %}
 8            {% set variable1 = 'El valor es 2' %}
 9        {% else %}
10            {% set variable1 = 'No entro' %}
11    {% endif %}
12
13    <para>Variable: {{ variable1 }}</para>
14</story>

Puede utilizar los siguientes operadores lógicos. Consulte la siguiente documentación para obtener más información .

Operador

Ejemplo de Uso

==

Usar el operador == para verificar si una variable es igual a un valor se puede eliminar si solo desea verificar si una variable no está vacía.

1<story>
2    {% if greeting %}
3        <para>Hola</para>
4    {% endif %}
5</story>

!=

No es igual a

1<story>
2    {% if greeting != 1 %}
3        <para>Hola</para>
4    {% endif %}
5</story>

<

Menor que

1<story>
2    {% if greeting < 3 %}
3        <para>Hola</para>
4    {% endif %}
5</story>

<=

Menor o igual que

1<story>
2    {% if greeting <= 3 %}
3        <para>Hola</para>
4    {% endif %}
5</story>

>

Mayor que

1<story>
2    {% if greeting > 1 %}
3        <para>Hola</para>
4    {% endif %}
5</story>

>=

Mayor o igual a

1<story>
2    {% if greeting >= 1 %}
3        <para>Hola</para>
4    {% endif %}
5</story>

and

Para comprobar si más de una condición es verdadera.

1<story>
2    {% if greeting == 1 and day == "Friday" %}
3        <para>Hola</para>
4    {% endif %}
5</story>

or

Para comprobar si una de las condiciones es verdadera.

1<story>
2    {% if greeting == 1 or greeting == 5 %}
3        <para>Hola</para>
4    {% endif %}
5</story>

and/or

Combina and y or.

1<story>
2    {% if greeting == 1 and day == "Friday" or greeting == 5 %}
3</story>
1{% if greeting == 1 and day == "Friday" or greeting == 5 %}

Bucles#

Un bucle for se utiliza para iterar sobre una secuencia, como recorrer elementos de una matriz, una lista o un diccionario.

1<story>
2    {% for item in sequence %}
3
4        ...
5
6    {% endfor %}
7</story>

Django tiene algunas variables que están disponibles dentro de un bucle. Las más utilizadas son las siguientes. Para obtener más información, consulte el siguiente enlace.

Atributo

Descripción

forloop.counter

La iteración actual, comenzando en 1.

1<ul>
2{% for x in fruits %}
3    <li>{{ forloop.counter }}</li>
4{% endfor %}
5</ul>

forloop.counter0

La iteración actual, comenzando en 0.

1<ul>
2{% for x in fruits %}
3    <li>{{ forloop.counter0 }}</li>
4{% endfor %}
5</ul>

forloop.first

Le permite probar si el bucle está en su primera iteración.

1{% for x in fruits %}
2<td>
3    {% if forloop.first %}
4    <para> ================ </para>
5    {% endif %}
6</td>
7{% endfor %}

forloop.last

Le permite probar si el bucle está en su última iteración.

1{% for x in fruits %}
2<td>
3    {% if forloop.last %}
4    <para> ================ </para>
5    {% endif %}
6</td>
7{% endfor %}

Acceso a atributos y métodos#

Puede acceder a la información de una variable utilizando un punto .. Al usar . después de la variable, está indicando que necesita acceder a un atributo o método específico del objeto que representa esa variable.

Las formas en que puede utilizar el punto son las siguientes:

  1. Búsqueda de diccionario

Si la variable es un diccionario, puede acceder a sus valores utilizando el nombre de la clave entre llaves, por ejemplo:

1{{ usuario.nombre }}
  1. Búsqueda de atributo o método

Si la variable es un objeto que tiene atributos o métodos, acceda a ellos utilizando el nombre correspondiente después del punto. Por ejemplo, si tiene un objeto producto y desea obtener su método calcular_precio(), lo puede hacer de la siguiente manera:

1{{ producto.calcular_precio }}
  1. Indexación numérica

Si la variable es una lista, puede acceder a elementos específicos. Por ejemplo, si tiene una lista de nombres y desea obtener el primer nombre, lo logra así:

1{{ nombres.0 }}

Answers#

Utilice la palabra reservada answers seguida del ID del campo de la forma para extraer información de sus formularios. Por ejemplo:

1{% set nombre = answers.646a69d6fb56c3sda00d7b036911216 %}

Prudencia

answers funciona de manera distinta para fotografías (imágenes), firmas, conjuntos repetitivos y documentos, ya que en estos casos se añade un tercer parámetro que corresponde a las URL.

Tags#

Existen etiquetas que regularmente son utilizadas en los documentos. Algunas de las comúnmente utilizadas son las siguientes.

Fechas#

Los formatos de fecha permiten personalizar la presentación de la fecha y la hora según lo requiera.

Y: Año con 4 dígitos.

m: Mes con ceros iniciales.

d: Día del mes con ceros iniciales.

H: Hora en formato de 24 horas.

i: Minutos.

s: Segundos.

 1<story>
 2    <!-- FECHAS -->
 3    <para> FECHA :   {% set_date_format meta.created_at "%Y-%m-%d" "%Y-%m-%d %H:%M:%S" %} </para>
 4
 5    <para> MES: {% get_month_txt answers.64c194dd696a295c093ef0a6 %} </para>
 6
 7    <para> DÍA: {% get_day_txt  answers.64c194dd696a295c093ef0a6 %} </para>
 8
 9    <para> DÍA ACTUAL: {% get_today "%d/%m/%Y %H:%M" %} </para>
10</story>

Cantidades#

Para realizar operaciones con cantidades, utilice la palabra reservada arithmetic.

 1<story>
 2    <!-- CANTIDADES -->
 3    {% set dinero1 = 5000.950 %}
 4    <para>DINERO: {% money_format dinero1 decimal_precision=0 thousand_separator='.' %}</para>
 5
 6    {% set valor1 = 0 %}
 7    {% set valor2 = 5 %}
 8    {% set resultado = 0 %}
 9    {% arithmetic 'resultado' 'valor1' '+' 'valor2' %}
10    <para>SUMA: {{ resultado }}</para>
11
12    {% set valor1 = 5 %}
13    {% set valor2 = 10 %}
14    {% set resultado = 0 %}
15    {% arithmetic 'resultado' 'valor2' '-' 'valor1' %}
16    <para>Resta: {{ resultado }}</para>
17
18    {% set valor1 = 5 %}
19    {% set valor2 = 10 %}
20    {% set resultado = 0 %}
21    {% arithmetic 'resultado' 'valor2' '*' 'valor1' %}
22    <para>Multiplicación: {{ resultado }}</para>
23
24    {% set valor1 = 5 %}
25    {% set valor2 = 10 %}
26    {% set resultado = 0 %}
27    {% arithmetic 'resultado' 'valor2' '/' 'valor1' %}
28    <para>División: {{ resultado }}</para>
29
30    {% set valor = 5 %}
31    <para>NOMBRE: {% number_to_txt valor %}</para>
32    <para>NOMBRE: {% number_to_txt valor 'PESOS M/CTE'%}</para>
33</story>

Concatenar#

Se refiere a la acción de unir o combinar múltiples cadenas de texto o valores en una sola cadena. La concatenación es útil cuando se desea combinar información de diferentes variables o campos para presentarla conjuntamente. Se utiliza la palabra reservada concat.

 1</story>
 2    <!-- CONCAT && AD -->
 3    {% set count = 0 %}
 4    {% set string = '' %}
 5
 6    {% for l in answers.61a669d6fb59c3df00d7bed036d %}
 7        {% add_total 'count' 1 %}
 8        {% concat 'string' count 'True' %}
 9
10        <para> Iteración: {{ count }} </para>
11    {% endfor %}
12    <para> Concatenación: {{ string }} </para>
13</story>

Imágenes#

Para tratar imágenes utilice una condicional para evaluar que exista algo en el campo.

1{% if answers.64c0644e130ce40b760135cd.0.file_url %}

Importante

Al utilizar la condicional if answers.64ce10644de130ce4s0b760135cd.0.file_url esta dando por hecho que solo hay una imagen o que solamente quiere mostrar la primera imagen que pueda estar en el campo. Si el campo contiene mas de una imagen debe utilizar un bucle for.

Dentro de la etiqueta <imageAndFlowables> se utiliza la custom tag get_thumbnail que permite traer una copia de la imagen real pero con menor peso para evitar que el pdf no pese demasiado.

 1</story>
 2    <!--IMÁGENES -->
 3
 4    <para> Imagen: </para>
 5    {% if answers.64c0644e130ce40b760135cd.0.file_url %}
 6        <imageAndFlowables
 7        imageName="{% get_thumbnail answers.64c0644e130ce40b760135cd.0.file_url  %}"
 8        imageWidth="10cm" imageHeight="6cm" imageSide="left" imageLeftPadding="4cm" />
 9    {% endif %}
10</story>

Truco

Recuerde que la etiqueta <imageAndFlowables> no permite centrar directamente la imagen. Por ello, juegue con los atributos que ofrece. En el caso anterior, tome el siguiente ejemplo: si tiene un ancho de 18 cm y su imagen mide 10 cm por defecto, le sobran 8 cm. Sepárelas utilizando imageLeftPadding e imageRightPadding para ajustar.

Ejemplos#

Con la información vista, contemple los siguientes casos de uso.

Catálogos#

Revise el siguiente ejemplo sobre catálogos.

Considere el siguiente ejemplo sobre un catálogo de Tiendas.

../../_images/201.png

Los catálogos son fáciles de consultar. Simplemente declare una variable seguida de la palabra reservada answers, seguido del Id del catálogo y luego el Id del campo, como se muestra a continuación:

1<para> Dirección: </para>
2{% set direccion = answers.6564fc4b7abbbbec1ea2b4ab.6564fc4b7abbbbec1ea2b4af %}
3<para>{{ direccion }}</para>

O de manera simplificada coloque:

1<para>Dirección: {{ answers.6564fc4b7abbbbec1ea2b4ab.6564fc4b7abbbbec1ea2b4af }}</para>

Si ejecuta los códigos anteriores, el resultado de ambas será:

1[u'Tijuana - Tecate, El Refugio, 22253, Plaza Sendero, Tijuana, B.C.']

La razón por la que se obtiene así es porque los datos están estructurados e interpretados como listas.

Para resolver ese problema, simplemente coloque .0. La notación .0 indica que necesita acceder al primer elemento de una lista o un conjunto. Por ejemplo:

1<para> Dirección: </para>
2{% set direccion = answers.6564fc4b7abbbbec1ea2b4ab.6564fc4b7abbbbec1ea2b4af.0 %}
3<para>{{ direccion }}</para>

A continuación, se presenta el código necesario para imprimir los datos de un catálogo:

 1<para style="textTitleI"> Cadena: </para>
 2{% set cadena = answers.6564fc4b7abbbbec1ea2b4ab.6564fc4b7abbbbec1ea2b4ac %}
 3<para>{{ cadena }}</para>
 4
 5<para style="textTitleI"> Tienda: </para>
 6{% set tienda = answers.6564fc4b7abbbbec1ea2b4ab.6564fc4b7abbbbec1ea2b4ae %}
 7<para>{{ tienda }}</para>
 8
 9<para style="textTitleI"> Dirección: </para>
10{% set direccion = answers.6564fc4b7abbbbec1ea2b4ab.6564fc4b7abbbbec1ea2b4af.0 %}
11<para>{{ direccion }}</para>
12
13<para style="textTitleI"> Estado: </para>
14{% set estado = answers.6564fc4b7abbbbec1ea2b4ab.6564fc4b7abbbbec1ea2b4b0.0 %}
15<para>{{ estado }}</para>
16
17<para style="textTitleI"> Municipio: </para>
18<para>{{ answers.6564fc4b7abbbbec1ea2b4ab.6564fc4b7abbbbec1ea2b4b1.0 }}</para>

El resultado del ejemplo es el siguiente. Para fines prácticos, se muestra de la siguiente manera; sin embargo, considere aplicar los Estilos necesarios:

../../_images/211.png

Ver también

En Django, al obtener datos de un formulario a veces es necesario acceder a elementos específicos de esa lista. Para saber cómo se presenta su información, puede inspeccionar la página en la que se encuentra su registro e inspeccionar sus datos y corroborar como viene la información.

Grupos repetitivos#

Contemple el siguiente ejemplo sobre grupos repetitivos:

Considere el siguiente grupo repetitivo Empleados.

../../_images/161.png

Para extraer datos de un grupo repetitivo de un formulario, siga los siguientes pasos:

  1. Especifique la tabla en la que desea representar el grupo repetitivo (linea 2-27).

  2. Declare un ciclo for para recorrer los elementos del grupo repetitivo colocando el id del mismo (linea 8).

  3. Si el campo es de tipo texto, simplemente llame la variable que utilizo para recorrer el grupo repetitivo seguido del id del campo (linea 12).

  4. Si dentro del grupo repetitivo hay imágenes, tenga en cuenta la siguientes consideraciones:

  • Si esta seguro de que el campo solo contendrá una imagen, podrá utilizar el siguiente código; donde está declarando la variable firma e igualándola al contenido de la imagen.

1{% set firma = item.64dd1d386170e28311ec20ff.file_url %}
2<imageAndFlowables imageName="{% get_thumbnail firma %}" imageWidth="5cm" imageHeight="2cm" imageSide="left"/>

Importante

Recuerde que una una firma es guardada y tratada como una imagen.

  • De lo contrario, si tiene mas de una imagen, deberá crear otro ciclo para mostrar todas las imágenes.

1{% for image in item.64dd1c61039ce8cf6a1a91e7 %}
2    {% set img = image.file_url %}
3    <imageAndFlowables imageName="{% get_thumbnail img %}" imageWidth="4cm" imageHeight="2cm" imageSide="left" />
4{% endfor %}
 1<story>
 2    <blockTable colWidths="5cm, 6cm, 6cm" style="general">
 3        <tr>
 4            <td><para> Nombre </para></td>
 5            <td><para> Fotografía </para></td>
 6            <td><para> Firma</para></td>
 7        </tr>
 8        {% for item in answers.64dd1bd4fd200a3308ec2140 %}
 9            <tr>
10                <td>
11                <para>
12                        {{ item.64dd1c61039ce8cf6a1a91e6 }}
13                </para>
14                </td>
15                <td>
16                    {% for image in item.64dd1c61039ce8cf6a1a91e7 %}
17                        {% set img = image.file_url %}
18                        <imageAndFlowables imageName="{% get_thumbnail img %}" imageWidth="4cm" imageHeight="2cm" imageSide="left" />
19                    {% endfor %}
20                </td>
21                <td>
22                    {% set firma = item.64dd1d386170e28311ec20ff.file_url %}
23                    <imageAndFlowables imageName="{% get_thumbnail firma %}" imageWidth="5cm" imageHeight="2cm" imageSide="left"/>
24                </td>
25            </tr>
26    {% endfor %}
27    </blockTable>
28</story>

El resultado del ejemplo es el siguiente. Para fines prácticos, se muestra de la siguiente manera, sin embargo, considere aplicar los Estilos necesarios:

../../_images/191.png

Custom Tags#

Las custom tags son etiquetas personalizadas de Linkaform para realizar tareas específicas en las plantillas que no pueden ser manejadas con las etiquetas existentes. A continuación, se presentan algunas etiquetas personalizadas (custom tags). Revise los comentarios en el código para obtener más información.

 1<!-- Contiene los metadatos de cada registros -->
 2meta
 3Code: {{ meta }}
 4Type: dict
 5
 6connection
 7Code: {{ meta.connection }}
 8Type: string
 9Default: 'N/A'
10
11<!-- Fecha de creación de registro en formato 'YYYY-MM-DD HH:mm:ss' -->
12created_at
13Code: {{ meta.created_at }}
14Type: string
15
16<!-- Nombre del usuario que creo el registro -->
17created_by_name
18Code: {{ meta.created_by_name }}
19Type: unicode string`
20
21<!-- Tiempo que tardo en crear el registro -->
22duration
23Code: {{ meta.duration }}
24Type: unicode string
25
26<!-- Fecha de finalización de registro en formato 'YYYY-MM-DD HH:mm:ss' -->
27end_date
28Code: {{ meta.end_date }}
29Type: string
30
31<!-- Folio del registro -->
32folio
33Code: {{ meta.folio }}
34Type: unicode string
35
36<!-- Contiene la url de google maps del creador/editor del registro (siempre y cuando el usuario permitió tomar la geolocalización) -->
37geolocation
38Code: {{ meta.geolocation }}
39Type: string
40
41points
42Code: {{ meta.points }}
43Type: int
44
45<!-- Fecha de inicio de creación/edición de registro en formato 'YYYY-MM-DD HH:mm:ss' -->
46start_date
47Code: {{ meta.start_date }}
48Type: string
49
50<!-- Fecha de última modificación de registro en formato 'YYYY-MM-DD HH:mm:ss' -->
51updated_at
52Code: {{ meta.updated_at }}
53Type: string
54
55<!-- Version del registro -->
56version
57Code: {{ meta.points }}
58Type: int

Importante

Anteriormente, se mencionó que el proceso para preparar su documento depende del código del mismo. Todo el contenido visto hasta ahora funciona de manera similar tanto para un documento de registro único como para un documento de múltiples registros. Sin embargo, para documentos de múltiples registros, debe colocar su código dentro de un bucle for para indicarle a Django que ejecute ese mismo código varias veces (por cada registro seleccionado) para procesar su información.

1</story>
2    {% for l in answers_list %}
3
4        <!-- Código -->
5
6    {% endfor %}
7</story>

En esta sección, aprendió el uso de Django Template Language para la creación de plantillas dinámicas, permitiéndole generar documentos adaptados a sus necesidades específicas. Aprendió el uso de variables, declaraciones condicionales y bucles, así como la forma de pasar y acceder a datos en las plantillas. Además, aprendió a cerca de custom tags (etiquetas personalizadas) para tareas específicas y la inclusión de imágenes en los documentos generados.

¡Felicidades! 🎉 Si ha seguido la documentación secuencialmente, ahora es capaz de generar sus propios documentos PDF personalizados. Si tiene alguna duda, puede regresar al contenido o consultar la documentación oficial de la sección de su preferencia.