Tiago Peres
Tiago Peres

Reputation: 15451

TypeError at /app/profile/ , 'list' object is not callable handle_pageBegin args=()

I want a button to create a PDF file (with Python 2.7, Django 1.8), but I have no clue how to express that to the machine.

I started by reading some articles, trying to learn from the others how could that be done.

Found this handy link, which redirected me to the following links:

So, in order to print as PDF:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Method one: using ReportLab /////////////////////////////////////////////////

pip install reportlab

ReportLab relies on Pillow, which is a third-party Python Image Library. If you run:

pip install Pillow

You'll see something like this:

Requirement already satisfied: Pillow in c:\pythonprojects\virtualenvs\apis\lib\site-packages
Requirement already satisfied: olefile in c:\pythonprojects\virtualenvs\apis\lib\site-packages (from Pillow)

Nothing else seems to be needed at this level, so let's start by making sure we have everything we need in the view.

------------------------------------------Version 0.2 (code was wrong)------------------------------------------

1. Code

# views.py
from django.http import response
from django.core.files.storage import FileSystemStorage
from django.shortcuts import render, HttpResponse
from django.contrib.auth.decorators import login_required
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch
import requests
import praw


def profile(request):
        #PDF
        doc = SimpleDocTemplate("test.pdf")
        styles = getSampleStyleSheet()
        Story = [Spacer(1, 2 * inch)]
        style = styles["Normal"]

        #Webpage
        parsedData = []
        userData = {}
        if request.method == 'POST':
        #Data
            sub = request.POST.get('subreddit')
            reddit = praw.Reddit(client_id='client_id',
                                 client_secret='client_secret',
                                 user_agent='user_agent')
            # assuming you have a Reddit instance bound to variable `reddit`
            subreddit = reddit.subreddit(sub)

            print('Master, this was the data retrieved that is going to be displayed:')
            print(subreddit.display_name)  # Output: redditdev
            print(subreddit.title)  # Output: reddit Development
            print(subreddit.description)  # Output: A subreddit for discussion of ...
            print('Tell me if you want more and I can give that to you, no problem-------------')

         #PDF
            print('Now, Im gonna create a PDF file with the same data...')
            subreddit_name = subreddit.display_name
            subreddit_title = subreddit.title
            subreddit_description = subreddit.description

            p = Paragraph(subreddit_name, subreddit_title, subreddit_description,  style)
            Story.append(p)
            Story.append(Spacer(1, 0.2 * inch))
            doc.build(Story)
            print('The file was created and can be accessed in the root of the Django project. The name is test.pdf')
            print('Tell me to stop if you dont like what Im doing-------------')        

        #Webpage
            print('OK. Time to give that to the user as well...')
            userData['subreddit_name'] = subreddit.display_name
            userData['title'] = subreddit.title
            userData['description'] = subreddit.description
        parsedData.append(userData)
        return render(request, 'app/profile.html', {'data': parsedData})

From the moment the code under #PDF was inserted, the view was never the same.

2. Errors

Traceback as image: enter image description here

Traceback as text:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/app/profile/

Django Version: 1.8
Python Version: 2.7.12
Installed Applications:
('frontend',
 'app',
 'blog',
 'suit',
 'suit_redactor',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware')


Traceback:
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\django\core\handlers\base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "C:\PythonProjects\reddit_development\demonstration\app\views.py" in profile
  69.         doc.build(Story)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\doctemplate.py" in build
  1213.         BaseDocTemplate.build(self,flowables, canvasmaker=canvasmaker)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\doctemplate.py" in build
  969.                     self.handle_flowable(flowables)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\doctemplate.py" in handle_flowable
  834.             if frame.add(f, canv, trySplit=self.allowSplitting):
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\frames.py" in _add
  167.                 w, h = flowable.wrap(aW, h)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\paragraph.py" in wrap
  1191.         leftIndent = style.leftIndent

Exception Type: AttributeError at /app/profile/
Exception Value: 'unicode' object has no attribute 'leftIndent'

3. Where I think is the problem?:

The code runs fine, until this part:

p = Paragraph(subreddit_name, subreddit_title, subreddit_description,  style)
Story.append(p)
Story.append(Spacer(1, 0.2 * inch))
doc.build(Story)

------------------------------------------Version 0.3 ----------------------------------------------

Accordingly to Christoph Bluoss in his message and to the documentation,

p = Paragraph("Some string", style)

Knowing this,

1. Code

a. Created 3 classes

Story1 = [Spacer(1, 2 * inch)]

Story2 = [Spacer(1, 2 * inch)]

Story3 = [Spacer(1, 2 * inch)]

b. Created 3 new variables

p1 = Paragraph(subreddit_name,  style)

p2 = Paragraph(subreddit_title, style)

p3 = Paragraph(subreddit_description, style)

c. Appended all of the variables in a different class each

Story1.append(p1)
Story1.append(Spacer(1, 0.2 * inch))

Story2.append(p2)
Story2.append(Spacer(1, 0.2 * inch))

Story3.append(p3)
Story3.append(Spacer(1, 0.2 * inch))

d. Did a doc.buil with those variables.

doc.build(Story1, Story2, Story3)

2. Errors

Traceback as image: enter image description here

Traceback as text:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/app/profile/

Django Version: 1.8
Python Version: 2.7.12
Installed Applications:
('frontend',
 'app',
 'blog',
 'suit',
 'suit_redactor',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware')


Traceback:
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\django\core\handlers\base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "C:\PythonProjects\reddit_development\demonstration\app\views.py" in profile
  77.         doc.build(Story1, Story2, Story3)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\doctemplate.py" in build
  1213.         BaseDocTemplate.build(self,flowables, canvasmaker=canvasmaker)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\doctemplate.py" in build
  966.                 self.clean_hanging()
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\doctemplate.py" in clean_hanging
  554.             self.handle_flowable(self._hanging)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\doctemplate.py" in handle_flowable
  828.             f.apply(self)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\doctemplate.py" in apply
  153.             annotateException("\nhandle_%s args=%s"%(action,ascii(args)))
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\lib\utils.py" in annotateException
  1390.     rl_reraise(t,v,b)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\doctemplate.py" in apply
  146.             getattr(doc,arn)(*args)
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\doctemplate.py" in handle_pageBegin
  1189.         self._handle_pageBegin()
File "C:\PythonProjects\virtualenvs\apis\lib\site-packages\reportlab\platypus\doctemplate.py" in handle_pageBegin
  579.         self.pageTemplate.onPage(self.canv,self)

Exception Type: TypeError at /app/profile/
Exception Value: 'list' object is not callable
handle_pageBegin args=()

3. Where I think is the problem:

The code runs fine, until this part:

 p1 = Paragraph(subreddit_name,  style)
 p2 = Paragraph(subreddit_title, style)
 p3 = Paragraph(subreddit_description, style)
 Story1.append(p1)
 Story1.append(Spacer(1, 0.2 * inch))
 Story2.append(p2)
 Story2.append(Spacer(1, 0.2 * inch))
 Story3.append(p3)
 Story3.append(Spacer(1, 0.2 * inch))
 doc.build(Story1, Story2, Story3)

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Method two: using WeasyPrint /////////////////////////////////////////////////

If we can't fix with the past method, this seems like a good deal.

Upvotes: 7

Views: 1188

Answers (2)

Christoph Bluoss
Christoph Bluoss

Reputation: 359

Answer to your updated problem (v 0.3) According to the documentation http://www.reportlab.com/docs/reportlab-userguide.pdf (page 68):

BaseDocTemplate.build(self, flowables, filename=None, canvasmaker=canvas.Canvas)

Assuming that the document instance is correctly set up the build method takes the story in the shape of the list of flowables (the flowables argument) and loops through the list forcing the flowables one at a time through the formatting machinery

While you on the other hand just called build() with a couple of lists instead. Actually, I don't even get why you're using 3 seperate lists at all and not just a single list like this in the first place.

story = [Spacer(1, 2 * inch)]
story.append(Paragraph(subreddit_name,  style))
story.append(Spacer(1, 2 * inch))
story.append(Paragraph(subreddit_title, style))
story.append(Spacer(1, 2 * inch))
story.append(Paragraph(subreddit_description, style))
doc.build(story)

which is working fine. (tested with python3 though)

Upvotes: 4

Christoph Bluoss
Christoph Bluoss

Reputation: 359

Looking at the Paragraph() documentation, the 2nd argument is the paragraph style. You're providing the subreddit_title instead, which is a regular unicode string and did not work.

Your code should look like this:

p = Paragraph("Some string", style)

And just my 2cents at the topic of pdf generation. I found http://weasyprint.org/ much more convenient to work with. Reportlab w/o a license is quite laborious to work with.

Upvotes: 2

Related Questions