Sending EmailMultiAlternatives in mail_admins() - django

I have the below view code snippet and I would like to send email as EmailMultiAlternatives to the admins, the problem is...it doesn't render the html tags.
Kindly assist with some ideas.
subject = "A New Feedback"
ctx = {
'name': name,
'email': email,
'message': message
}
message = ('ecoke/includes/email_feedback.html', ctx)
mail_admins(subject, message, fail_silently=True, html_message='text/html')

mail_admins is a wrapper around send_mail.
In the send_mail documentation html_message is described as the HTML message to be attached to the email where as message is the plain text string.
From what you have above you will need to render (render_to_string) the message and attach it as HTML.
subject = "A New Feedback"
ctx = {
'name': name,
'email': email,
'message': message
}
html_message = render_to_string(
'ecoke/includes/email_feedback.html',
context=ctx
)
text_message = 'Hi %s, <plain text goes here>' % name
mail_admins(subject, text_message, fail_silently=True, html_message=html_message)
What happens is that you have two versions of the text; one for plain text one for HTML. As the HTML is not rendered by mail_admins you will need to render the template to HTML manually. The HTML message is attached as an alternative as illustrated here.

Related

Django - Html tags in email template

I' m using Django signals to send emails when a new record is added:
#receiver(post_save, sender=MeetingMember)
def send_invited_emails(sender, instance, **kwargs):
host = instance.meeting.host
subject = "Mizban invition"
# htmly = get_template('sendingemail.html')
domain = Site.objects.get_current().domain
context={'host':host,'meeting': instance,'domain':domain}
html_content = render_to_string('sendingemail.html',context)
send_mail(subject, html_content, settings.EMAIL_HOST_USER,[instance.email])
This code works but it sends html tags in email as well how can I solve the issue?
The second parameter message is the message you want to display as raw text. You can pass the content of a HTML message through the html_message=… parameter of the send_mail(…) function [Django-doc]:
# …
html_content = render_to_string('sendingemail.html',context)
send_mail(
subject,
html_content,
settings.EMAIL_HOST_USER,[instance.email],
html_message=html_content
)
Usually for the message, one also creates a text variant of the message: one without HTML that can be used by simple email clients to display the email on a console terminal for example.

How to send a file from Django to Gmail?

There is a feedback form in which the user can write a text message and attach the file.
This form is sent to managers by mail (gmail, for example).
Is there any way to make this file come to mail in its normal form (in a preview, for example) so that you can immediately see or download it?
For now, I'm just sending a file link in the message.
Thanks for help #dirkgroten
def send_contact_us_notification(file, name: str, email: str, body: str, phone='', nda=False):
try:
file = settings.MEDIA_URL[1:] + str(contact_form.file)
from django.core.mail import EmailMessage
msg = EmailMessage('Subject of the Email', 'Body of the email', 'dinamo.mutu111#gmailcom', ['dimaonlyvit#gmail.com'])
msg.attach_file(file)
msg.send()
except Exception as e:
print(e)

Send templates emails Django 1.11 error (html tags in letter)

I am trying to send template emails.
Code:
def send_admin_notification(ticket):
subject = "Notification: NEW TICKET."
to = [DEFAULT_ADMIN_EMAIL]
from_email = settings.DEFAULT_FROM_EMAIL
template = 'emails/admin.html'
ctx = {
"ticket_id": ticket.id,
"subject": ticket.subject,
"text": ticket.support_text,
"email": ticket.email,
}
message = render_to_string(template, ctx)
msg = EmailMessage(subject, message, to=to, from_email=from_email)
msg.send()
But the letter comes with all html tags how to send letter without html tags ?
Any help would be appreciated. Thanks!
From the documentation for EmailMessage:
body: The body text. This should be a plain text message.
To send HTML messages, you need to use django.core.mail.EmailMultiAlternatives instead of EmailMessage. The documentation provides an example that includes a HTML message.
Alternatively you can use django.core.mail.send_mail which accepts a html_message argument, something like this:
from django.core.mail import send_mail
def send_admin_notification(ticket):
subject = "Notification: NEW TICKET."
from_email = settings.DEFAULT_FROM_EMAIL
tpl= 'emails/admin.html'
html_message = render_to_string(tpl, ctx)
send_mail(
subject=subject ,
message='', # Plain text version of message - advisable to provide this
from_email=from_email
recipient_list=[DEFAULT_ADMIN_EMAIL],
html_message=html_message
)

recipient_list send mail just to the first address in the list

I´m using signals to send mails to the users depending of some actions. In one of my signals I need to send the same mail to multiple users, my signal use post_save so for the parameter [recipient_list] I use this instance.email_list email_list is where I store the list of email addresses to send the mail, they are stored in this format user1#mail.com, user2#mail.com, user3#mail.com.
To send the emails I use EMAIL_HOST = 'smtp.gmail.com' the problem is that the only user who recive the email is the first one in the list. So I 'log in' in the gmail account to check the send emails section and actually in the "to" area of the email shows that was send to all the users in the list but the emails never arrive just for the first email address in the list.
I read that if google detect that the account sends a lot of messages could be blocked but only send like 5 emails at the same time and when I'm in the account never shows me some alert or something.
So the problem is how I send the emails or maybe some bad configuration of the gmail account?
Any help is really appreciated.
Sorry for my bad grammar.
EDIT: Here's my code.
forms.py
class MyForm(forms.Form):
userslist = forms.ModelChoiceField(queryset = User.objects.filter(here goes my condition to show the users), empty_label='List of users', label='Users', required=False)
emailaddress = forms.CharField(max_length=1000, label='Send to:', required=False)
comment = forms.CharField(widget=CKEditorUploadingWidget(), label="Comment:")
That form display a list of users to select the email address in the field emailaddress store the values. This is my Ajax to bring the email address:
views.py
class mails(TemplateView):
def get(self, request, *args, **kwargs):
id_user = request.GET['id']
us = User.objects.filter(id = id_user)
data = serializers.serialize('json', us, fields=('email'))
return HttpResponse(data, content_type='application/json')
And here's the <script> I use to populate the emailaddres field:
<script>
$('#id_userlist').on('change', concatenate);
function concatenate() {
var id = $(this).val();
$.ajax({
data: { 'id': id },
url: '/the_url_to_get_data/',
type: 'get',
success: function (data) {
var mail = ""
for (var i = 0; i < data.length; i++) {
mail += data[i].fields.email;
}
var orig = $('#id_emailaddress').val();
$('#id_emailaddress').val(orig + mail + ',');
}
})
}
</script>
The signal I use to send the mail is this:
#receiver(post_save, sender=ModelOfMyForm, dispatch_uid='mails_signal')
def mails_signal(sender, instance, **kwargs):
if kwargs.get('created', False):
if instance.emailaddress:
#Here goes the code for the subject, plane_message,
#from_email and template_message.
send_mail(subject, plane_message, from_email, [instance.emailaddress], fail_silently=False, html_message=template_message)
So if I select 4 users the info is save in this way in the database:
Then I 'log in' in the account to check the 'Sent Mail' section and check the detail of the mail and shows that was send to the 4 users but the only user who recibe the mail was the first in the list.
Your problem is that you are passing a comma-separated string of email addresses inside instance.emailaddress (first#gmail.com, second#hotmail.com, third#hotmail.com etc). Django expects a Python list of addresses, not a comma separated string. It will just ignore everything after the first comma.
Change your code as follows and it will work:
def mails_signal(sender, instance, **kwargs):
if kwargs.get('created', False):
if instance.emailaddress:
#Here goes the code for the subject, plane_message,
#from_email and template_message.
recipients = [r.strip() for r in instance.emailaddress.split(',')]
send_mail(subject, plane_message, from_email, recipients, fail_silently=False, html_message=template_message)

Keeping DRY with sending mail in Django

I have the following two blocks of code in a LOT of my views. Im looking for a way to abstract them so that instead of repeating this code in every view. The receipent, subject line and body will vary of course, so I would like to be able to pass those strings to this function--"function" is the right term to use, correct?
mailt = loader.get_template('membership/signup_email.txt')
mailc = Context({
'signin_url': signin_url,
'name': firstname + ' ' + lastname,
'username': username,
'membership_level': membership_level.name,
'membership_number': membership_number,
'payment_plan': payment_plan
})
msg = EmailMessage(
'You are now a Member!',
mailt.render(mailc),
'membership#domain.org',
[email]
)
msg.content_subtype = "html"
msg.send()
# Nofity our staff
admin_mailt = loader.get_template('membership/signup_admin_email.txt')
admin_mailc = Context({
'site': current_site,
'user': user,
'payment_plan': payment_plan
})
admin_msg = EmailMessage(
'[myproject] New Membership Signup',
admin_mailt.render(admin_mailc),
'membership#domain.org',
['membership#domain.org']
)
admin_msg.content_subtype = "html"
admin_msg.send()
I'm not sure where your variables are all coming from...but....could you simply create a function in say a utils.py? Put the above code in there and call it with parameters when needed. So your views might have something like follows. A call to a function you created elsewhere.
custom_send_mail(recipient, subject, body)
You could use the built in django email methods and abstract them a little to get what you want, it won't buy you that much, but here you go.
See the documentation here: http://docs.djangoproject.com/en/1.3/topics/email/
Here is how you use the built in django email method.
from django.core.mail import send_mail
send_mail('Subject here', 'Here is the message.', 'from#example.com',
['to#example.com'], fail_silently=False)
So one of your examples above would turn into this.
# Nofity our staff
admin_mailt = loader.get_template('membership/signup_admin_email.txt')
admin_mailc = Context({
'site': current_site,
'user': user,
'payment_plan': payment_plan
})
send_mail('[myproject] New Membership Signup', admin_mailt.render(admin_mailc), 'membership#domain.org', ['membership#domain.org'])
You could wrap this a little so that you could just pass in the template name and the context and it would make it a little cleaner.
send_my_email(subject, to_address, template, context, from_address='membership#domain.org'):
admin_mailt = loader.get_template(template)
send_mail(subject, admin_mailt.render(context), from_address, to_address)