iniciante, gerando pdf usando o reportlab

788 views
Skip to first unread message

Mário Neto

unread,
Jan 15, 2009, 10:34:04 PM1/15/09
to django...@googlegroups.com
Oi pessoal, estou persistindo nesse belo framework:
Quero carregar uma lista de livros dentro de um arquivo pdf,

# arquivo model.py da aplicação manterLivro:

from django.db import models
from django.contrib import admin

class Livro(models.Model):
    nome = models.CharField(max_length=50)
    publicacao = models.DateField()

class LivroAdmin(admin.ModelAdmin):
    fields = ['nome', 'publicacao']
    
admin.site.register(Livro, LivroAdmin)

# arquivo views.py da aplicação manterLivro:

# -*- coding:utf-8 -*-
from livros.manterLivro.models import Livro

from reportlab.pdfgen import canvas
from django.http import HttpResponse

def indexPdf(request):
    response = HttpResponse(mimetype='application/pdf')
    response['Content-Disposition'] = 'attachment; filename=gerado.pdf'

    lista_livros = Livro.objects.all().order_by('-publicacao')[:5]

    def for_livros():
        for lv in lista_livros:
            return str(lv)

    p = canvas.Canvas(response)
    p.drawString(100, 100, for_livros())

    p.showPage()
    p.save()
    return response

# Ao carregar a url, a aplicação me retorna um PDF:

Apenas com o texto: Livro object

Onde será que estou errando?

Abraço! =)

Luciano Ramalho

unread,
Jan 16, 2009, 5:43:45 AM1/16/09
to django...@googlegroups.com
2009/1/16 Mário Neto <macnd...@gmail.com>:

Caro Mário Neto,

Veja esta linha na sua função for_livros:

> return str(lv)

Esta linha faz duas coisas:

1) a expressão str(lv) gera uma string a partir do objeto lv, que é um
livro. Como isso funciona? Os tutoriais de Python e de Django explicam
que a função str() invoca o método __str__ do seu objeto. Se você não
definiu este método __str__ no seu modelo de Livro, então aparece
exatamente o que você mostrou: "Livro object". No Django este é um
recurso básico, pois permite customizar o que aparece nas listagens do
admin, por exemplo. Se quiser gerar uma saída Unicode, use a função
unicode(), que por sua vez invocará o método __unicode__.

2) o comando return encerra imediatamente a execução da função e
devolve o valor da expressão para o contexto que invocou a função. Por
este motivo, aparece apenas um livro no seu PDF: o loop for dentro da
função for_livros é executado apenas uma vez, pois o processamento da
função termina no return.

Mário, me perdôe se eu pareço chato ao insistir neste ponto, mas a
seguir eu vou dar uma resposta que eu costumo dar muitas vezes nesta e
em outras listas ligadas a Python: estude o tutorial de Python [1],
disponível em português:

http://www.pythonbrasil.com.br/moin.cgi/TutorialPython

Se você se dedicar um tempo a ler este tutorial inteiro, do começo até
o final, aprenderá muitos recursos essenciais da linguagem, que
aumentarão muito a sua produtividade.

Python tem uma sintaxe muito simples, o que é ótimo, mas em
consequência às vezes a gente observa as pessoas usando a linguagem
"de orelhada", aplicando conceitos aprendidos em outras linguagens.
Essa estratégia até funciona inicialmente, mas pode consolidar vícios
de programação que a longo prazo vão te gerar muitos problemas e perda
de tempo. Evite isso e faça como todos os gurus de Python que eu
conheço: leia o tutorial escrito pelo autor da linguagem com atenção,
do começo até o final, e aproveite muito melhor o seu tempo
trabalhando com esta linguagem maravilhosa.

[ ]s
Luciano

Luciano Ramalho

unread,
Jan 16, 2009, 5:43:45 AM1/16/09
to django...@googlegroups.com
2009/1/16 Mário Neto <macnd...@gmail.com>:

Caro Mário Neto,

Mário Neto

unread,
Jan 16, 2009, 8:06:02 AM1/16/09
to django...@googlegroups.com
Luciano,
 
Valeu pelas dicas, ao chegar em casa tentarei aplica-las, quanto a estudar python eu já até imprimi esse tutorial completo e estou lendo. Aprendendo muitos recursos da linguagem, axo que isso foi mais falta de atenção também, porquê eu quero so os nomes dos livros, e não coloquei lv.nome, aliás fazendo isso ele já retornou o nome do livro mas retornou apenas um resultado, exatamente como vc colocou ao citar o return. Só vou tentar fazer com que ele retorne todos os resultados da lista.
 
valeu!

2009/1/16 Luciano Ramalho <ram...@gmail.com>

Mário Neto

unread,
Jan 16, 2009, 8:08:50 AM1/16/09
to django...@googlegroups.com
aproveitando a deixa, você acha que isso vai funcionar?
 

def indexPdf(request):
    response = HttpResponse(mimetype='application/pdf')
    response['Content-Disposition'] = 'attachment; filename=gerado.pdf'

    lista_livros = Livro.objects.all().order_by('-publicacao')[:5]

    p = canvas.Canvas(response)

    for lv in lista_livros:
        p.drawString(100, 100, str(lv.nome))

    p.showPage()
    p.save()
    return response


2009/1/16 Mário Neto <macnd...@gmail.com>
Reply all
Reply to author
Forward
0 new messages