Search code examples
pythondjango-rest-frameworkpython-docxdocxtpl

¿How to generate a .docx document with python-docx-template (docxtpl)? Django Python


I am trying to generate a .docx document in Django for this I am using docxtpl (Python docx template) that generates documents through .docx templates. I try to generate the document with this data:

listaFinal = [
   [
      {
         "-":"LIBROS"
      },
      {
         "":"Responsabilidad Social de las Organizaciones (RSO): Avances y propuestas en América Latina",
         "Editorial":"Imprenta Editora Gráfica Real",
         "Año":2015,
         "Páginas":457,
         "Tipo Libro":53
      }
   ],
   [
      {
         "-":"ARTICULOS"
      },
      {
         "":"Gestión universitaria ética y responsable. Indicadores de RSU  ",
         "Link Articulo":"http://www.revistalatinacs.org/13SLCS/2013_actas/170_Valarezo.pdf",
         "issn":"",
         "nombre_conferencia":"V Congreso Internacional Latina de Comunicación  Social – V CILCS – Universidad de La Laguna, diciembre 2013 "
      },
      {
         "":"Universidad Tecnica Particular de Loja. Proceso de internacionalización de la UTPL",
         "Link Articulo":"http://www.iesalc.unesco.org.ve/index.php?option=com_content&view=article&id=1786&Itemid=1147&lang=es",
         "issn":"",
         "nombre_conferencia":""
      }
   ]
]

In my .views I have this where I indicate the path of my template docx_filename.docx and send the data in context:

def generaraDocumento(request):
    response = HttpResponse(content_type='application/msword')
    response['Content-Disposition'] = 'attachment; filename="cv.docx"'

    doc = DocxTemplate(str(settings.BASE_DIR) + '/cv_api/templates/docx_filename.docx')
    context = {'listaFinal': listaFinal}

    doc.render(context)
    doc.save(response)

    return response

I have a template called docx_filename.docx what I do is that in this template I indicate how I want the result to be, in my .docx template I have this to be able to display the data in the file:

{% for lista in listaFinal %}
    {% for i in lista %}
        {% for clave, valor in i.items %}
            {% if forloop.first %}
                {% if clave == '-' %} 
                    {{ clave }} 
                {% endif %}
            {% else %}
                {% if clave %}
                    {{ clave }} 
                {% endif %}  
                    {{ valor }}
            {% endif %}
        {% endfor %}
    {% endfor %}
{% endfor %}

It gives me an error like this: Exception Value: 'builtin_function_or_method' object is not iterable.

I know something is wrong in the for of my docx_filename.docx template that I try to iterate to listaFinal. How can I iterate correctly so that the data is painted in my .docx file. I look forward to any help or suggestion. Thanks in advance.


Solution

  • I was able to solve it this way:

    {% for lista in listaFinal %}
        {% for i in lista %}
            {% for clave, valor in i.items() %}
                {% if loop.first  %}
                    {% if clave == '-' %} 
                        {{ clave }} 
                    {% endif %}
                {% else %}
                    {% if clave %}
                        {{ clave }} 
                    {% endif %}  
                        {{ valor }}
                {% endif %}
            {% endfor %}
        {% endfor %}
    {% endfor %}
    

    Changing the following: {% for clave, valor in i.items %} for this {% for clave, valor in i.items() %} and {% if forloop.first %} for this: {% if loop.first %}