I have def that render to pdf with action on django-admin.
def Print(self, request, obj):
data = {
'obj':obj
}
pdf = render_to_pdf('daa/imprimir/pdf.html', data)
if pdf :
response = HttpResponse(pdf, content_type='application/pdf')
filename ="Avaria_%s.pdf" %("123451231")
content = "inline; filename='%s'" %(filename)
response['Content-Disposition'] = content
download = request.GET.get("download")
if download:
content = "attachment; filename='%s'" %(filename)
response['Content-Disposition'] = content
return response
return HttpResponse("Not found")
and on my actions I have:
class ModelAdmin(admin.ModelAdmin):
actions = [Print]
and it is working all good, I select what objects I want to render and in my html I have cicles that make a list of all fields I want of those obj's.
But right now I don't want to render to pdf a list. I want to render only 1 obj. So I create a custom button to do that.
http://prntscr.com/muijhl
So when I click on button I want to render to pdf the obj which is open. I don't know what I need to do to take my def and but inside of button
For how to hook this code as a view with it's own url, there's a perfect example in the official doc (but you have to know what to look for to find it)
Then you'll have to override your change_form template to add the button/link pointing to this url.
Related
Why in this PDF file generated in this example not able to add watermark . How can I fix it? (There is no error, just does not able to display "WATERMARK".).
template_name = assign_custom_template(template_name)
template_path = template_name
e_library_list = Elibrary.objects.get(pk=e_library_id,)
retrun_questionlist = {}
for e_library_question_list in e_library_list.products.all():
questionlist = MCQAnswerFiled.objects.filter(group__pk=e_library_question_list.id)
retrun_questionlist[e_library_question_list.id] = questionlist
context = {'e_library_list': e_library_list,'retrun_questionlist':retrun_questionlist}
# Create a Django response object, and specify content_type as pdf
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="report.pdf"'
# find the template and render it.
template = get_template(template_path)
html = render_to_string(template_path, context)
response = BytesIO()
file = open('sheetstudentcopy.pdf', "w+b")
pdf = pisa.pisaDocument(BytesIO(html.encode("UTF-8")), file,link_callback=link_callback)
file.seek(0)
pdf = file.read()
file.close()
return HttpResponse(pdf, 'application/pdf')
You should include the watermark image directly into your CSS template, as described in the documentation:
https://xhtml2pdf.readthedocs.io/en/latest/reference.html#page-background-image
For example:
#page {
background-image: url('/path/to/pdf-background.jpg');
}
I just started to use Django, and I want to create a button that will initiate a PDF download with a header and a footer. for the PDF I use Reportlab. In the Django documentation, they say to use the Canvas object, but I cannot add a footer and a header with canvas. Can anyone give me a piece of code that will return a response from a view in Django with a PDF download with footer and header?
thank you!
Extending BaseDocTemplate allows you to define a Frame contained within a PageTemplate. Flowables are used in the frame so your content can flow over to other pages. The header and footer are just strings of text placed on the Canvas outside of the frame. saveState() and restoreState() have to be used when defining a header and footer so that it repeats on each page of your pdf.
class HeaderFooterTemplate(BaseDocTemplate):
def __init__(self, filename, **kwargs):
self.report_title = kwargs['report_title']
self.pagesize = kwargs['pagesize']
BaseDocTemplate.__init__(self, filename, **kwargs)
main_frame = Frame(
0, 0, self.pagesize[0], self.pagesize[1], topPadding=25, bottomPadding=18, id='main_frame')
template = PageTemplate(id='frame', frames=[main_frame], onPage=self.header_footer)
self.addPageTemplates([template])
def header_footer(self, canv, doc):
canv.saveState()
canv.setPageSize(doc.pagesize)
canv.setTitle(doc.title)
# header
canv.drawCentredString(doc.pagesize[0] / 2, doc.pagesize[1] - 15, self.report_title)
# footer
date_printed = 'Date Printed: ' + dateformat.format(timezone.localtime(timezone.now()), 'Y-m-d f A')
footer_date = canv.beginText(0, 2)
footer_date.textLine(date_printed)
canv.drawText(footer_date)
canv.restoreState()
class PdfTest:
def __init__(self):
self.buffer = BytesIO()
self.pagesize = letter
self.story = []
def build_pdf(self, filename):
"""
Get the value of the BytesIO buffer and write it to the response.
:param filename: name of the file when downloading
"""
pdf = self.buffer.getvalue()
self.buffer.close()
if pdf:
response = HttpResponse(pdf, content_type='application/pdf')
content = 'inline; filename="%s"' % filename
response['Content-Disposition'] = content
return response
def draw(self):
style = styles["Normal"]
for i in range(100):
bogustext = ("This is Paragraph number %s. " % i) *20
p = Paragraph(bogustext, style)
self.story.append(p)
self.story.append(Spacer(1,0.2*inch))
doc = HeaderFooterTemplate(self.buffer, pagesize=self.pagesize, report_title='Test Header Footer PDF')
doc.build(self.story)
return self.build_pdf('test.pdf')
class PdfView(View):
def get(self, request):
pdf = PdfTest()
return pdf.draw()
I created a file in project, generation pdf from html. For this i have this method:
def generation_html_to_pdf(self):
path_pdf = None
with NamedTemporaryFile(delete=False, suffix=".pdf", dir='pdf_files') as tf:
path_pdf = tf.name
pdfkit.from_file('templates/first_page.html', tf.name)
return path_pdf
Then, in pdf_files folder i have the pdf file. I want to get a download link for this file:
my view
path_to_pdf = generation_html_to_pdf()
download_link = 'http://' + request.get_host() + path_to_pdf
json_inf_pdf = {'download_link': download_link}
return JsonResponse(json_inf_pdf, status=200)
i have json like this:
{"download_link": "http://127.0.0.1:8000/home/alex/projects/test_project/pdf_files/tmpe0nqbn01.pdf"}"
when i click in this link i have error:
Page not found (404)
You need to create download view and url. Function like this to create link:
def download_link(request):
''' Create download link '''
download_link = 'http://{}/{}'.format(request.get_host(), 'download/my_filename')
json_inf_pdf = {'download_link': download_link}
return JsonResponse(json_inf_pdf, status=200)
and to download pdf:
def download_file(request, my_filename):
''' Download file '''
# Open template
from django.conf import settings
template_url = os.path.join(settings.BASE_DIR, 'templates', 'first_page.html')
template_open = open(template_url, 'r')
# Read template
from django import template
t = template.Template(template_open.read())
c = template.Context({})
# Create pdf
pdf = pdfkit.from_string(t.render(c))
# Create and return response with created pdf
response = HttpResponse(pdf)
response['Content-Type'] = 'application/pdf'
response['Content-disposition'] = 'attachment ; filename = {}'.format(my_filename)
return response
and url:
path('/download/<str:my_filename>', views.download_file, name="download_pdf')
I can't guarantee that this will work in your case without modification, since I can't tell which html-to-pdf library you're using and without seeing your other code. It's just a basic implementation idea.
I have this view, which takes a user_id and image_id. When the user cliks the link, check if there is an image. If there is, then I would like the file to force download automatically.
template:
<a class="downloadBtn" :href="website + '/download-image/'+ user_id+'/'+ image_id +'/'">Download</a>
Before I was developing it in my local machine, and this code was working.
#api_view(['GET'])
#permission_classes([AllowAny])
def download_image(request, user_id=None, image_id=None):
try:
ui = UserImage.objects.get(user=user_id, image=image_id)
content_type = mimetypes.guess_type(ui.image.url)
wrapper = FileWrapper(open(str(ui.image.file)))
response = HttpResponse(wrapper, content_type=content_type)
response['Content-Disposition'] = 'attachment; filename="image.jpeg'
return response
except UserImage.DoesNotExist:
...
But now I am using aws s3 for my static and media files. I am using django-storages and boto3. How can I force download the image in the browser?
#api_view(['GET'])
#permission_classes([AllowAny])
def download_image(request, user_id=None, image_id=None):
try:
ui = UserImage.objects.get(user=user_id, image=image_id)
url = ui.image.url
...
... FORCE DOWNLOAD THE IMAGE
...
except UserImage.DoesNotExist:
...
... ERROR, NO IMAGE AVAILABLE
...
You can just return a HttpResponse with the image itself.
return HttpResponse(instance.image, content_type="image/jpeg")
This will return the image's byte stream. The Content-type header is to show the images in platforms like Postman.
I am trying to display some csv(comma seperated values) in my project. So I have a html button click upon which a django view function is called through JavaScript. This is my django view function :
def make_csv(request):
testdata = "[{\"severity\":\"0\",\"description\":\"USB Connected\",\"date\":\"01/01/2015\",\"time\":\"11:35:20\"},{\"severity\":\"3\",\"description\":\"USB Disconnected\",\"date\":\"01/01/2015\",\"time\":\"10:30:19\"}]";
data = json.loads(testdata)
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="eventlog.csv"'
writer = csv.writer(response,csv.excel)
writer.writerow(data[0].keys())
for row in data:
writer.writerow(row.values())
return response
But I can't get any file displayed in my browser. Also I can see the values returned using my JavaScript. Is there a way to display the result as a seperate file in the browser so that users can download it?