Django mass email - get single recipient address in every email template - python

I'm sending email in Django:
...
recipient_list = ['first#recipient.com', 'second#recipient.com',]
mail = EmailMessage('Subject', 'content body', [sender#email.com], recipient_list)
mail.send()
In the template I'm rendering I would like to extract single recipient like this.
template.html
...
This message was sent at {{ datetime_sent }} to address {{ recipient_address }}.
I don't want to pass recipient_list in every email in case of mass email, but rather a single recipient address. Is this possible?

You won't be able to customise this sort of information sending the same email to more than one recipient. What you will want is to use Django's mass mail function, see here:
https://docs.djangoproject.com/en/4.0/topics/email/#send-mass-mail
You can access the recipient as {{ mail.to }} in your template

Related

Django how to send html-designed email bodies

On my Django project I am trying to send beautiful mails with colorful body and so on. My mail body constructing function looks like the following:
def construct_mail_body():
user = User.objects.get(id=1)
context = {
'username': user.username,
}
template = render_to_string('mail/mail_body.html', context=context)
message = strip_tags(template)
return message
mail_body.html:
{% load static %}
<h3>Hello <span style="color: red;">{{ username }}</span>,</h3>
<h3>You've successfully completed our Tutorial!></h3>
<h3>Congratulations!</h3>
But it doesn't work as expected. My mail bodies looks like:
Body 1:
Body 2 (Btw, why this happens? Why the mail is in purple?):
So how to make HTML tags work properly and is it possible to add some styling properties of css?
Thanks!
Solved:
I found a way how to do that:
from django.core.mail import EmailMessage
mail = EmailMessage(
subject,
body,
settings.EMAIL_HOST_USER,
[email],
)
mail.fail_silently = False
mail.content_subtype = 'html'
mail.send()
This way it works properly.
This is possible, but stick to hex colours, e.g. #ff0000, instead of a named colour.
Text can all go purple, as Willem commented, when something is repeated, or for replies. If you change the subject line when testing, it won't group them, and so it won't do this.
Keep using inline CSS, but stick to HTML4 and CSS2 (higher can be achieved but as a progressive enhancement for some email clients only).

Send Django Email User Register Confirmation with with custom header name

I want to send Django email confirmation email, it shows the admin added email address (that we configure in settings.py) as the header of the newly arrived email, but I want to change it to something else my personal Header Title, like The Google Team, I want to replace my email as others showing in the picture.
https://prnt.sc/1mo2xeo
You can use "YOUR NAME <abc#domain.com>" as the email address you send from_email.
from django.core.mail import EmailMessage
email = EmailMessage()
email.subject = 'subject'
email.body = 'message'
email.from_email = 'YOUR NAME <abc#domain.com>'
email.to = ['to#domain.com']
email.send()

Request Approvals by E-mail and process it Python + Django

Maybe I am not asking the right question in the search area, but I can't find an answer for this. I am pretty sure that many people have this use case, but as a beginner in Django + Python, I need to ask it.
I have user that fills up a form and the data is stored in the database. Basically this form asks for an access to a Database and after the form is submitted I want my program to send an email to the user's manager and to the DBA to APPROVE or DENY it. Very simple, right?
My idea is that in this e-mail I send two URL's, one for approving and one for denying the request. When the URL the is clicked I send a response to the server with an update in the manager_approval field.
Has anyone implemented this solution, or could point me to something that could help me?
I am doing everything using Django + Python.
Regards,
Marcos Freccia
Basically this technique used in email verification. This is where you should look into.
Let's say you have model, named request, which has field like username to identify the person who requested access, database name, well, everything. But it will also have two "password-like" fields which will be used to determine if request was declined or not.
class Request(models.Model):
user = models.ForeignKey ...
databasename =
date =
...
access_granted = models.BooleanField(default=False)
deny_token = models.CharField()
allow_token = models.CharField()
The point is to generate those tokens on saving request in the View:
if request.method == POST:
form = RequestForm(request.POST)
if form.is_valid():
data['user'] = form.cleaned_data['user'])
data['databasename'] = form.cleaned_data['databasename'])
...
data['access_token'] = GENERATE_USING_HASH_FUNCTION()
data['deny_token'] = GENERATE_USING_HASH_FUNCTION()
form.save(data)
Then you can use module EmailMultiAlternatives to send html email like so:
subject, from_email, to = 'Request', 'admin#example.com', form.cleaned_data['manager_email']
html_content = render_to_string(HTML_TEMPLATE, CONTEXT) # Just as any regular templates
text_content = strip_tags(html_content)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to], reply_to=["admin#example.com"])
msg.attach_alternative(html_content, "text/html")
msg.send()
And inside that template you construct reverse url:
{% url 'app:grant_access' allow_token=token %} # "token" you get from context
{% url 'app:deny_access' deny_token=token %} # will become example.com/deny_access/7ea3c95, where 7ea3c95 is token
Then add lines to urls.py of your app like that:
url(r'^allow_access/(?P<allow_token>[0-9]+)$', CheckAcessView.as_view(), name="app:grant_access"),
url(r'^deny_access/(?P<deny_token>[0-9]+)$', CheckAcessView.as_view(), name="app:deny_access"),]
Then create CheckAcessView view. Where you access request stored in your database and check if, for example, parameter of url "allow_token" is equal stored allow_token. If so, change request status to allowed.

Django EmailMultiAlternatives sending to multiple "to" addresses

Is there a way in Django EmailMultiAlternatives that you can send to multiple "to" addresses, without having to send it again?
Have tried separating the email int the tuple by commas, but only the first recipient receives the emails.
A list of email addresses should work, as the example in the Django docs shows.
to_emails = ['alice#example.com', 'bob#example.com']
msg = EmailMultiAlternatives(subject, text_content, from_email, to_emails)
You might want to use bcc instead of to_emails to prevent users from seeing the other recipients of the email.
msg = EmailMultiAlternatives(subject, text_content, from_email, bcc=to_emails)
I'm using a for loop. I'm also using this to filter which users emails are sent to.
for user in users:
if user.is_active and user != request.user and user.last_login != None:
message = EmailMultiAlternatives(
subject = "your subject here",
from_email = settings.EMAIL_HOST_USER,
to = [user.email],
)
context = {'request':request, 'user':user, 'event':event}
html_template = get_template("notifications/new_event_email.html").render(context)
message.attach_alternative(html_template, "text/html")
message.send()
It might not be the best way, but it's working for me.

Error: SMTPRecipientsRefused 553, '5.7.1 #while working on contact form in django

im trying to make a contact form in django 1.3, python 2.6.
Whats the reason of following error?
error:
SMTPRecipientsRefused at /contact/
{'test#test.megiteam.pl': (553, '5.7.1 <randomacc#hotmail.com>: Sender address
rejected: not owned by user test#test.megiteam.pl')}
my settings.py:
EMAIL_HOST = 'test.megiteam.pl'
EMAIL_HOST_USER = 'test#test.megiteam.pl'
EMAIL_HOST_PASSWORD = '###'
DEFAULT_FROM_EMAIL = 'test#test.megiteam.pl'
SERVER_EMAIL = 'test#test.megiteam.pl'
EMAIL_USE_TLS = True
edit: If any1 else was following djangobook, this is the part causing it:
send_mail(
request.POST['subject'],
request.POST['message'],
request.POST.get('email', 'noreply#example.com'), #get rid of 'email'
['siteowner#example.com'],
The explanation is in the error message. Your email host is rejecting the email because of the sender address randomacc#hotmail.com that you have taken from the contact form.
Instead, you should use your own email address as the sender address. You can use the reply_to option so that replies go to your user.
email = EmailMessage(
'Subject',
'Body goes here',
'test#test.megiteam.pl',
['to#example.com',],
reply_to='randomacc#hotmail.com',
)
email.send()
On Django 1.7 and earlier, there isn't a reply_to argument, but you can manually set a Reply-To header:
email = EmailMessage(
'Subject',
'Body goes here',
'test#test.megiteam.pl',
['to#example.com',],
headers = {'Reply-To': 'randomacc#hotmail.com'},
)
email.send()
Edit:
In the comments you asked how to include the sender's address in the message body. The message and from_email are just strings, so you can combine them however you want before you send the email.
Note that you shouldn't get the from_email argument from your cleaned_data. You know that the from_address should be test#test.megiteam.pl, so use that, or maybe import DEFAULT_FROM_EMAIL from your settings.
Note that if you create a message using EmailMessage as in my example above, and set the reply to header, then your email client should do the right thing when you hit the reply button. The example below uses send_mail to keep it similar to the code you linked to.
from django.conf import settings
...
if form.is_valid():
cd = form.cleaned_data
message = cd['message']
# construct the message body from the form's cleaned data
body = """\
from: %s
message: %s""" % (cd['email'], cd['message'])
send_mail(
cd['subject'],
body,
settings.DEFAULT_FROM_EMAIL, # use your email address, not the one from the form
['test#test.megiteam.pl'],
)

Categories