El Blog de Trespams

Blog personal sobre tecnologia, gestió de projectes i coses que se me passen pel cap

Mails amb Django - II

Enviar un e-mail fent servir plantilles Django

Com ja tots sabeu Django té un sistema de plantilles molt eficaç. Normalment les fem servir per mostrar l'html de les nostres aplicacions web, però no estan limitades a això, i com veurem les podem fer servir per generar els nostre correu.

La manera de fer-ho és fent servir render_to_string que podem trobar a django.template.loader. Aquesta funció agafa com a paràmetres el nom de la plantilla que volem fer servir i un diccionari amb els paràmetres que farem servir a la plantilla. Agafa un tercer paràmetre, que ha de ser de tipus Context, però que per als nostres objectius no la farem servir gaire.

Quan volem enviar un correu ho podem fer dins la vista, però sovint ho farem des de classes d'utilitat, el model o un formulari, on el request no està disponible. Per això hem de tenir em compte que la majoria de vegades no tindrem accés a les variables que normalment estan accessibles a les plantilles mitjançant el context processors. Així doncs que si el correu te links pensau que tot el que siguin referències a arxius i links forçosament necessiten de Sites, MEDIA_URL i STATIC_URL (o fer servir el tag {% static %} introduït a les darreres versions de Django.

Suposem doncs que tenim el seguent, dins una plantilla que hem anomenta newsletter.html i que tenim accessible dins els TEMPLATE_DIRS

Benvolgut {{user.get_fullname}}, No deixis de visitar les nostres ofertes a http://{{current_site}}/ofertes/ Salutacions, -- info@{{current_site}} http://{{current_site}}

I a la funció que genera el correu tendríem per exemple:

from django.contrib.sites.models import Site
from django.conf import settings
from django.template.loader import render_to_string
from django.core.mail import EmailMessage


def send_wellcome():
"""Envia un missatge als nostres usuaris"""
current_site = Site.objects.get_current().domain
context = {'current_site': current_site}
for u in User.objects.all():
context['user'] = u
body = render_to_string('dos/newsletter.html', context)
msg = EmailMessage(subject="hello", body=body, from_email="jo@apsl.net", to=['someuser@example.com'])
msg.content_subtype = "html"
msg.send()

Fixem-nos com context és un diccionari on li hem de passar totes les variables que utilitza la nostra plantilla. En aquests tipus de corrreus el més habitual és anar en pilot automàtica i fer servir les variables {{STATIC_URL}} o {{MEDIA_URL}} habituats a tenir-les accessibles gràcies als context_processors i trobar-nos que als nostres e-mails no es veuen les imatges. Així que a més de passar-les al context ens hem d'assegurar que es passen aquestes variables i a més que les urls es generen com a url absolutes.

Per això a la plantilla de Django podem fer servir la llibreria static i utilitzar els tags get_static_prefix i get_media_prefixper a generar les urls. Seria una cosa semblant a

{% load static %}
{% get_static_prefix as STATIC_PREFIX %}
{% get_media_prefix as MEDI_PREFIX %}

<img src="http://{{current_site}}/{{STATIC_PREFIX}}/img/log.jpg" alt="logo" />

<img src="http://{{current_site}}/{{MEDIA_PREFIX}}/profile/{{foto}}" alt="foot pujada" />

No fa falta recordar que a static hi posarem totes aquelles images, css, js, etc que formen part de l'estructura de l'aplicació i a media hi haurà totes aquelles imatges i continguts que puja l'usuari de la nostra aplicació.

Donat que hem utilitzat en render_to_string per a generar el cos del missatge, segur que a més d'un se li haurà acudit que podem fer el mateix amb el subject, doncs sí, si és necessari es pot fer i de fet es fa. Però això ja serà al proper article...

blog comments powered by Disqus