sexta-feira, 19 de abril de 2013

Gerando um PDF para download ou arquivo a partir de um Template em Django

Você vai precisar dos seguintes aplicativos instalados no ENV:

  • html5lib==0.95
  • pisa==3.0.33
  • reportlab==2.7

Crie um arquivo chamado report.py na raiz do seu projeto com o conteúdo abaixo:
# -*- coding: utf-8 -*-
from django import http
from django.conf import settings
from django.http import HttpResponse
from django.template import Context
from django.template import RequestContext
from django.template.loader import get_template
from django.template.loader import render_to_string
import cgi, os
import cStringIO as StringIO
import ho.pisa as pisa

def fetch_resources(uri, rel):
    path = os.path.join(settings.STATIC_PATH, uri.replace(settings.MEDIA_URL, ""))
    return path

def write_to_pdf(template_src, context_dict, filename):
    template = get_template(template_src)
    context = Context(context_dict)
    html  = template.render(context)
    result = StringIO.StringIO()
    pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")), result, link_callback=fetch_resources)
    if not pdf.err:
        response = http.HttpResponse(mimetype='application/pdf')
        response['Content-Disposition'] = 'attachment; filename=%s.pdf' % filename
        response.write(result.getvalue())

        # OPCIONAL, CASO QUEIRA GERAR O ARQUIVO EM DISCO
        f = open('%s/uploads/projetos/%s.pdf' % (settings.MEDIA_ROOT, filename), 'w+')
        f.write(result.getvalue())
        f.close()


        return response

    return http.HttpResponse('Problema ao gerar PDF: %s' % cgi.escape(html))

Crie a view que será responsável pela chamada da geração do PDF:
from app.report import write_to_pdf

def projeto2pdf(request, slug=None):
    projeto = get_object_or_404(Projeto, slug=slug)
    response = write_to_pdf('template_pdf.html', {'projeto': projeto}, projeto.slug)
    return response

Caso seu template possua alguma imagem, lembre-se de colocar nos src das tags img apenas o caminho a partir do caminho definido na def fetch_resorces do arquivo report.py

...
<img src="site/img/sua_imagem.png" alt="imagem" width="176" height="103">
...

Agora basta criar a url para a chamada da view:
...
url(r'^projeto2pdf/(?P<slug>[-\w]+)/$', 'projeto2pdf', name='projeto2pdf'),
...

hasta!

domingo, 7 de abril de 2013

Enviando email multi-formato (txt, html) com EmailMultiAlternatives

# ENVIANDO EMAIL DE CADASTRO
from django.template import Context, loader, RequestContext
from django.core.mail import EmailMultiAlternatives

tHtml = loader.get_template('email/cadastro.html')
tTxt = loader.get_template('email/cadastro.txt')

c = Context({
 'email': self.email,
 'senha': self.senha,
})

destinatario = []
destinatario.append(self.email)
subject = "PROMOÇÃO INOVE SUA COZINHA com WICKBOLD"
emailFrom = ""
      
text_content = tTxt.render(c)
html_content = tHtml.render(c)
msg = EmailMultiAlternatives(subject, text_content, emailFrom, destinatario)
msg.attach_alternative(html_content, "text/html")
   
try:
 msg.send()
except:
 pass

quinta-feira, 4 de abril de 2013

NoReverseMatch Exception Value: u"'" is not a registered namespace

Nas versões mais novas do Django (1.4+), o comportamento da tag {% url %} utilizada nos templates mudou, e para continuar utilizando, agora com suporte aos NAMESPACES, deve-se fazer conforme abaixo:


No urls.py utilize namespaces conforme abaixo:
 url(r'^', include('appviews.urls', namespace='appsite')),

Certifique-se que no template que deseja utilizar a tag {% url %} tenha o import abaixo:
{% load url from future %}

Para utilizar a tag {% url %} em seus links, utilize a nova sintaxe:
<a href="{% url '<NAMESPACE>:<URL_NAME>' %}">Seu link</a>




hasta!