How can I convert a HTML Page to PDF using Django - python

I have a web app in Django. It's a plataform to store bills and invoices. Now i'm trying to export those bills un PDF.
I'm using xhtml2pdf but it's not working.
I'm using this code for testing:
http://obroll.com/generate-pdf-with-xhtml2pdf-pisa-in-django-examples/
It doesnt give any errors but doesnt generate the PDF documentos.

Try using this code. It works for me.
Change "template_testing.html" for your template and add your data to render on "data = {}"
views.py:
import os
from django.conf import settings
from django.http import HttpResponse
from django.template import Context
from django.template.loader import get_template
import datetime
from xhtml2pdf import pisa
def generate_PDF(request):
data = {}
template = get_template('template_testing.html')
html = template.render(Context(data))
file = open('test.pdf', "w+b")
pisaStatus = pisa.CreatePDF(html.encode('utf-8'), dest=file,
encoding='utf-8')
file.seek(0)
pdf = file.read()
file.close()
return HttpResponse(pdf, 'application/pdf')

Related

connection error while using requests module in my django project

I was trying to create a django project. Everything was fine until I did a get request using requests.get() in python in my views.py
Following is what my views.py have
from django.http import HttpResponse
from django.shortcuts import render
import re, requests
def codify_data(data_raw):
data = data_raw.json()['data']
if language == 'web':
html_cd = data['sourceCode']
css_cd = data['cssCode']
js_cd = data['jsCode']
def home_page(request):
return render(request,'home/index.html')
def code(request):
link = request.GET.get('link', 'https://code.sololearn.com/c5I5H9T7viyb/?ref=app')
result = re.search(r'https://code.sololearn.com/(.*)/?ref=app',link).group(1)[0:-2]
data_raw = requests.get('https://api2.sololearn.com/v2/codeplayground/usercodes/'+result)
codify_data(data_raw)
The error is shown below:

Could I use InMemoryUploadedFile directly to upload Image to Imgur?

I have some problems about uploading image to Imgur by using Django.
I have finished that Image File uploaded from react and delivered File data to backend via Axios.
But the object I got from the request.data in Python backend is InMemoryUploadedFile.
I don't want to store any image files in my disk.
Could I use directly this file which is a InMemoryUploadedFile type to upload by Imgur upload function upload_from_path?
If so, how can I do?
Here are my code,
from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.response import Response
from django.contrib.auth.models import User
from base.models import InCome, IncomeMoneyCategory, IncomeContributeContext,OutcomeMoneyCategory, OutcomeContributeContext, Member, Student, OutCome
from django.db.models import F, Sum
from base.serializers import IncomeSerializer, OutcomeSerializer
from rest_framework import status
from datetime import datetime
import configparser
import base.config as env
import os
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from django.conf import settings
from imgurpython import ImgurClient
#api_view(['POST'])
def upload_image(request):
data = request.data
print(data)
album = env.IMGUR_ALBUM
print(data['image'])
image=data['image']
print("--")
print(type(image))
image_path=image
config = configparser.ConfigParser()
path = '/'.join((os.path.abspath(__file__).replace('\\', '/')).split('/')[:-1])
config.read(os.path.join(path, 'auth.ini'))
#config.read('auth.ini')
client_id = config['credentials']['client_id']
client_secret = config['credentials']['client_secret']
refresh_token = config['credentials']['refresh_token']
access_token = config['credentials']['access_token']
client = ImgurClient(client_id,client_secret, refresh_token)
client.set_user_auth(access_token, refresh_token)
if client:
config={
'album':album,
'name':'Ezra',
'title':'Test',
'description': 'Test {0}'.format(datetime.now())
}
print("Uploading image")
image = client.upload_from_path(str(image_path),config=config,anon=False)
print(image['link'])
print("Done")
return image
else:return "Error"
The type of image is <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>.
But the first one parameter in the function ImgurClient.upload_from_path of imgurpython package needs the file name to upload.
So when I execute this code, I'll get this Error:
No such file or directory:...
Hope someone can help me to solve it, and sorry for my poor English.
Thank you for reading.
I have solved it later.
I used default_storage to save the file and gave the directory as the first parameter in the upload_from_path method.
After uploading to Imgur, I deleted the files and return link back.
Here is my code:
def upload_image(request):
data = request.data
album = env.IMGUR_ALBUM
image=data['image']
file = data['image']
filename = default_storage.save(file.name, ContentFile(file.read()))
config = configparser.ConfigParser()
path = '/'.join((os.path.abspath(__file__).replace('\\', '/')).split('/')[:-1])
config.read(os.path.join(path, 'auth.ini'))
client_id = config['credentials']['client_id']
client_secret = config['credentials']['client_secret']
refresh_token = config['credentials']['refresh_token']
access_token = config['credentials']['access_token']
client = ImgurClient(client_id,client_secret, refresh_token)
client.set_user_auth(access_token, refresh_token)
if client:
config={
'album':album,
'name':'Ezra',
'title':'Test',
'description': 'Test {0}'.format(datetime.now())
}
print("Uploading image")
image = client.upload_from_path(settings.MEDIA_ROOT+'/'+filename,config=config,anon=False)
print("Done")
default_storage.delete(filename)
return Response(image['link'])
else:return "Error"

Pdf in django-rest-framework

I am trying to make pdf in Django
from xhtml2pdf import pisa
from django.http import HttpResponse
from django.template.loader import get_template
from django.template import Context
from rest_framework.views import APIView
from .models import Brand
class ABCView(APIView):
def post(self, request,format=None):
report = Brand.objects.all()
template_path = 'profile_brand_report.html'
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="Report.pdf"'
context = {'report': report}
template = get_template(template_path)
html = template.render(Context(context))
print (html)
pisaStatus = pisa.CreatePDF(html, dest=response)
return response
but I am getting an unexpected error I don't know what I am doing wrong, I am getting this error
argument of type 'Context' is not iterable
or is there any other way to do it .thanks for help in advance
We don't need to use a class based view for it. For simplicity we can use a function based view. Change your code as below.
from django.template.loader import render_to_string
def generate_pdf(request):
report = Brand.objects.all()
template_path = 'profile_brand_report.html'
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="Report.pdf"'
html = render_to_string(template_path, {'report': report})
print (html)
pisaStatus = pisa.CreatePDF(html, dest=response)
return response
We can also use wkhtmltopdf to generate PDF's in django.
Read: https://learnbatta.com/blog/django-html-to-pdf-using-pdfkit-and-wkhtmltopdf-5/

Django: "initial_value must be str or None, not bytes" error

While learning Django and Python I am trying to download a pdf file. The files content should be from a html template. I am trying to do this using the pisaDocument example(and any other example from the internet are exactyle the same). In my case I am getting the: initial_value must be str or None, not bytes error on the StringIO(html.encode("utf-8")) part. I understand that the problem is that StringIo need a str and it returns bytes, but how can i convert the bytes to str?
from django.http import HttpResponse, Http404
from django.shortcuts import render, redirect
from django.template.loader import get_template
from django.views.decorators.csrf import csrf_exempt
from io import StringIO, BytesIO
from cgi import escape
def export(request):
if(request.POST):
client = request.POST.get('client')
doc = request.POST.get('doc')
template = get_template('files/insurance.html.twig')
html = template.render()
result = StringIO(html)
pdf = pisa.pisaDocument(StringIO(html.encode("utf-8")), result)
if not pdf.err:
return HttpResponse(result.getvalue(), content_type='application/pdf')
return HttpResponse('We had some errors<pre>%s</pre>' % escape(html))
else:
raise Http404("POST data not found")

get Json data from request with Django

I'm trying to develop a very simple script in Django, I'd collect a Json data from the request and then store all data in the database.
I developed one python script that I'm using to send the Json data to the Django view, but I'm doing something wrong and I can't understand what, because every time that I run it,I've got "Malformed data!".
Can someone helps me? what am I doing wrong?
Sender.py
import json
import urllib2
data = {
'ids': ["milan", "rome","florence"]
}
req = urllib2.Request('http://127.0.0.1:8000/value/')
req.add_header('Content-Type', 'application/json')
response = urllib2.urlopen(req, json.dumps(data))
Django view.py
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
import json
from models import *
from django.http import StreamingHttpResponse
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def value(request):
try:
data = json.loads(request.body)
label = data['label']
url = data ['url']
print label, url
except:
return HttpResponse("Malformed data!")
return HttpResponse("Got json data")
Your dictionary "data" in sender.py contains only one value with key "ids" but in view.py you are trying to access keys "label" and "url" in this parsed dictionary.

Categories