I am fairly new to Django but I’ve been stuck on a problem for several days. I have been trying to find answers online without any success.
I have a view called CreateReportView where I am trying to use weasyprint to generate a pdf that gets downloaded. In the future I want to be able to save the bytes array to a database, so a user can see the generated reports and then to download them. But a first step is just being able to download the generated pdf. When using the weasyprint write_pdf() method and saving to disc, e.g. to test.pdf, the pdf is ok when opening the file. However, when I try to generate the PDF to a variable and save it in either File- or HTTPresponse as an attachment, I only get text with characters in the browser that looks like this:
%PDF-1.7 %???? 5 0 obj <> stream xڽXm 6 _ ? 9 IpZ [(]h n ܧ p r d ή ױg yy ( G 1 @ ? z
I have tried everything I can think of, such as changing between Http- and FileResponse, saving the file temporary to the disc, opening it and then passing it to the respons; using a buffer; etc.. I have also tried using the Reportlab library and I get the same problem. To clarify, when I tried using the HttpResponse, I used the following code:
response = HttpResponse(content_type='application/pdf;')
response['Content-Disposition'] = 'application; filename=list_equipamentos.pdf'
I saw that someone solved the problem using a buffer (Using Weasyprint to create file response), but it didn’t work for me. The code for this is commented in the view below. I get the same problem
I found that someone else solved it by changing a ‘traffic-cop’ routine, but I cant seem to find the code that needs to be changed (Django – can’t download file (showed as text instead)).
Also, when using the inspection mode in Chrome, I saw that the response includes the necessary headers such as content-disposition and and content-type.
Any help or guidance would be greatly appreciated. Let me know if you need further information.
Thank you in advance!
from django.core.files import File
from django.db.models import Avg, Count, Case, When, IntegerField, DecimalField
from django.http import HttpResponse, FileResponse
from django.shortcuts import render
from django.template.loader import render_to_string
from django.views import View
from weasyprint import HTML
from salary.models import Salary
class CreateReportView(View):
def get(self, request, *args, ** kwargs):
... # Omitted unrelevant code
context = context={'results': results, 'results_per_gender': results_per_gender, 'results_per_region': results_per_region, 'results_titles': results_titles}
rendered_html = render_to_string('report_template.html', context=context)
# buffer = io.BytesIO()
# pdf_file = HTML(string=rendered_html)
# pdf_file.write_pdf(buffer)
pdf_file = HTML(string=rendered_html).write_pdf()
# buffer.seek(0)
response = FileResponse(pdf_file, as_attachment=True, filename="test.pdf")
return response
samuelh is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.