I want to send a mail to the subscribers of a django website. So, as soon as someone registers they should be sent a mail. I can do this by the send_mail function that django has but I want to send a designed mail (like with a mail chimp template). Any ideas on how to do this? I read through the api documentation and understood how to send mails but I cannot understand how to integrate its own template and stuff.
Any advice will be helpful. Thanks!
MailChimp templates are just HTML. If you are using Django 1.7+, send_email supports html_message (ref).
You can use the render_to_string (see here) function to output the appropriate HTML, which will be fed into send_email. Combining these two, you can first set up your HTML template:
html_template = render_to_string('templates/my_email.html', {'foo': 'bar'})
Then create my_email.html and put the HTML generated on MailChimp into that file.
You can now call send_mail with the new HTML template:
send_mail(
[...]
html_message=html_template,
)
EDIT: Full example:
from django.core.mail import send_mail
from django.template.loader import render_to_string
html_template = render_to_string('templates/my_email.html', {'foo': 'bar'})
send_mail(
'Title',
'Plaintext Version Goes Here',
'sender#sender.com',
['receiver#receiver.com'],
html_message=html_template,
)
Related
Im using django_yubin to send mails via its mail queue.
However, there are a few instances where I want to send the mail immediately without putting it on the queue.
For example, when a user registers or resets their password. Or certain admin emails.
I tried using Django's built in email system by
from django.core.mail import send_mail as send_mail_core
and then using the send_mail_core() function.
This didnt work - looks like the send_mail in django.core.mail gets overridden by yubin
Thanks for your help
Why would you even try to use send_mail_core if you can select the mail backend inside of send_mail function
def send_mail(subject, message, from_email, recipient_list,
fail_silently=False, auth_user=None, auth_password=None,
connection=None, html_message=None):
connection: The optional email backend to use to send the mail. If
unspecified, an instance of the default backend will be used. See the
documentation on Email backends for more details.
Can I send an html formatted document as the body of an email and include an attachment?
send_mail() has an option for html_message but the EmailMessage class does not.
My understanding is that to send an attachment, I need to use the EmailMessage class to use the attach_file method.
Am I missing something? I thought send_mail() uses the EmailMessage class, so why do these two features seem mutually exclusive?
Check out EmailMultiAlternatives it has an attach function that you can use for this purpose.
Here's an example of how to use it:
from django.core.mail import EmailMultiAlternatives
subject = request.POST.get('subject', '')
message = request.POST.get('message', '').encode("utf-8")
# Create an e-mail
email_message = EmailMultiAlternatives(
subject=subject,
body=message,
from_email=conn.username,
to=recipents,
bcc=bcc_recipents, # ['bcc#example.com'],
cc=cc_recipents,
headers = {'Reply-To': request.user.email},
connection = connection
)
email_message.attach_alternative(message, "text/html")
for a in matachments:
email_message.attach(a.name, a.document.read())
email_message.send()
I see that to have an html email, I can have html as the body, but I just need to change the content_subtype to html.
msg_body.content_subtype = "html"
Thanks for your help, it got me back to the right page to read in better detail.
I'm using the django helper method send_mail, which might be the problem, but I cannot tell from the docs if that is the case.
So - here is my method:
send_mail('Alert!', theEmail.format(user.username),'admin#site.com',
[user.email], fail_silently=False)
And theEmail looks like this:
theEmail = """
Hi {0}! Here is an alert email
And here is a link: a link in time
But when i run this code, the email sends fine - but in gmail, the message is printed with all the tags visible.
Is there some sort of "send as html" thing i'm meant to do ?
try something like:
from django.core.mail import EmailMessage
msg = EmailMessage(subject, html, from_email, [recipients])
msg.content_subtype = 'html'
msg.send()
You can play around with some of Django's built-in functions to escape the html string before sending (maybe gmail does some escaping/unescaping themself), e.g.:
from django.utils.safestring import mark_for_escaping
my_html = mark_for_escaping(my_raw_html)
or
from django.utils.safestring import mark_safe
my_html = mark_safe(my_raw_html)
send_mail does not support a feature like "send as html".
Try use html_message argument:
send_mail('Alert!', '', 'admin#site.com', [user.email], html_message=theEmail.format(user.username), fail_silently=False)
Ive been requested by a client that his satchmo store should send an html formatted mail when resetting his password.
Aparently satchmo or django's contrib.auth.views.password_reset sends only raw email.
How do I modify this in order to be able to send html formatted mails?
Thank you!
I haven't used Satchmo, but this should get you started.
First of all, subclass the PasswordResetForm, and override the save method to send an html email instead of a plain text email.
from django.contrib.auth.forms import PasswordResetForm
class HTMLPasswordResetForm(PasswordResetForm):
def save(self, domain_override=None, email_template_name='registration/password_reset_email.html',
use_https=False, token_generator=default_token_generator, from_email=None, request=None):
"""
Generates a one-use only link for resetting password and sends to the user
"""
# Left as an exercise to the reader
You can use the existing PasswordResetForm as a guide. You need replace the send_mail call at the end with code to send html emails. The docs about sending html emails should help.
Once you've written your form, you need to include the form in the url pattern for password_reset. As I said, I don't have any experience of Satchmo, but looking at the source code, I think you want to update satchmo_store.accounts.urls, by changing the password_reset_dict.
# You need to import your form, or define it in this module
from myapp.forms import HTMLPasswordResetForm
#Dictionary for authentication views
password_reset_dict = {
'template_name': 'registration/password_reset_form.html',
# You might want the change the email template to .html
'email_template_name': 'registration/password_reset.txt',
'password_reset_form': HTMLPasswordResetForm,
}
# the "from email" in password reset is problematic... it is hard coded as None
urlpatterns += patterns('django.contrib.auth.views',
(r'^password_reset/$', 'password_reset', password_reset_dict, 'auth_password_reset'),
...
I want to substitute build-in send_mail function, that works only with plain-text emails, with my own smart send_mail function, that generates both html and plain-text versions automatically. Everything works as expected for my own emails, defined in my own application. I can do it in views.py in this fashion:
from django.core import mail
from utils import send_mail as send_html_mail
mail.send_mail = send_html_mail
But the problem still appears with emails of third-side applications. There all imports already completed before my code with monkey-patching of send_mail function.
Is it possible to override this function before all imports of all django applications? Or may be there is another solution of this issue. I really don't want to patch code with sending emails of these third-party applications. It's much easy just to put html-template.
Django 1.2 allows for pluggable email backends: http://docs.djangoproject.com/en/1.2/topics/email/#defining-a-custom-e-mail-backend
From Django docs: http://docs.djangoproject.com/en/dev/topics/email/#sending-alternative-content-types
from django.core.mail import EmailMultiAlternatives
subject, from_email, to = 'hello', 'from#example.com', 'to#example.com'
text_content = 'This is an important message.'
html_content = '<p>This is an <strong>important</strong> message.</p>'
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()
No send_mail() required.
Sounds like a lot of people are misreading your question.
To override the import from third party modules, overwriting sys.modules['django.core.mail'] might work.
It works in simple tests, but it's not thoroughly tested.
import sys
from django.core import mail
def my_send_mail(*args, **kwargs):
print "Sent!11"
mail.send_mail = my_send_mail
sys.modules['django.core.mail'] = mail
from django.core.mail import send_mail
send_mail('blah')
# output: Sent!11
For example, if I put that code in my settings.py and launch the manage.py shell and import send_mail, I get my version.
My shell session
In [1]: from django.core.mail import send_mail
In [2]: send_mail()
Sent!11
Disclaimer
I've never done anything like this and don't know if there are any funky ramifications.
I wrote application for quickly switching from plain-text emails to html based emails for all project's applications. It will work without modifying any Django code or code of other third-part applications.
Check it out here: https://github.com/ramusus/django-email-html
How about changing django a little and substituting original code with your own function? You can actually just add your own function and don't remove the old, as the last definition will be imported. I don't like such solutions, because I don't like patching external libraries (you need to remember about patching them again when you upgrade), but this would solve your problem quickly.
In Django 1.7 added extra attribute html_message to send_mail() function to send html message.
https://docs.djangoproject.com/en/1.8/topics/email/#send-mail