does django send_mail() support custom 'from'? - django

my django app is sending emails (via SendGrid API) using django.core.mail's send_mail
send_mail(
subject='foo',
message=message,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=[user.email],
fail_silently=False,
html_message=rendered)
the emails send fine but since it's sending from hi#myapp.com the email "From" alias in inboxes just shows up as "hi", and I'd like to make it more verbose so my recipients know who sent them the email ("Hi from AppName"). I don't see any field in send_mail docs (https://docs.djangoproject.com/en/2.1/topics/email/) for customizing how the "From" sender alias string appears (beyond the email itself) other than 'The “From:” header of the email will be the value of the SERVER_EMAIL setting'. does django's send_mail not support this (i.e., I need to rewrite this to using a sendgrid lib? https://github.com/sendgrid/sendgrid-python?) or is there a config setting in SendGrid where I can automatically set 'fromname'? thanks
Is that

Your example includes from_email=settings.DEFAULT_FROM_EMAIL. The docs say that the more verbose form is permitted, for example:
from_email="Hi from Appname <hi#myapp.com>",
You might also be able to change DEFAULT_FROM_EMAIL to the more verbose form. However the docs don't say whether this is supported or not, so I'm not sure whether this would cause problems somewhere.

Related

How to validate email before send mail and finding whether the mail send - django

I use - is_valid = validate_email(e) for validating email. It can detect if '#' is not present or some more but not providing whether the email entered is active now. AND I used sendmail for sending email. I used try except block. Mail is sending but sometimes try code running and someother times except block is running. How to avoid this abnormal behaviour.
if i correctly understand your question..
There is an option called emailfield in djangoforms.it will show validation error if # is not present.
field_name = forms.EmailField(**options)

Django-templated-email does not send email

I am using the following package https://github.com/vintasoftware/django-templated-email in a Django app to try and send an email. I am running it inside a django management command.
When I run the command the email part outputs to the console but no email is actually sent out. The SMTP settings and such are correct as emails work fine for other areas of the application.
from templated_email import send_templated_mail
send_templated_mail(
template_name='welcome',
from_email='from#example.com',
recipient_list=['to#example.com'],
context={
'username':"test",
'full_name':"test",
'signup_date':"test"
},
)
Any help is appreciated. I suspect I have misunderstood the syntax of the package.
Signup_date must be date and username and full_name must use single quote

Unsure of how to manage email configurations

I am attempting to create Reset Password functionality using Djoser. I am successfully hitting my API's auth/users/reset_password/ endpoint, which is then sending an email as expected. But the problem is occurring in the content of the email. It is sending a redirection link to my api, rather than to my frontend.
Please note, any <> is simply hiding a variable and is not actually displayed like that
Here is an example of what the email looks like:
You're receiving this email because you requested a password reset for your user account at <api>.
Please go to the following page and choose a new password: <api>/reset-password/confirm/<uid>/<token>
Your username, in case you've forgotten: <username>
Thanks for using our site!
The <api> team
The goal with this email is to send the user to the /reset-password/confirm/ url on my frontend, not on my api, which is currently occurring.
Here are my DJOSER settings:
DJOSER = {
'DOMAIN': '<frontend>',
'SITE_NAME': '<site-name>',
'PASSWORD_RESET_CONFIRM_URL': 'reset-password/confirm/{uid}/{token}',
}
The expected behavior is for the DOMAIN setting to alter the link that is being placed in the email, but it is not. I can't seem to find reference to this particular problem within the docs.
Any help here would be greatly appreciated, thanks.
I figured it out:
Due to Djoser extending the package django-templated-mail, the variables DOMAIN and SITE_NAME have to override django-templated-mail setting rather than Djoser's setting. So, you have to pull variables specific to django-templated-mail out of the Djoser variable.
The working setup actually looks like:
DOMAIN = '<frontend>',
SITE_NAME = '<site-name>',
DJOSER = {
'PASSWORD_RESET_CONFIRM_URL': 'reset-password/confirm/{uid}/{token}',
}

Testing Django email backend

In my settings.py, I put:
EMAIL_BACKEND = 'mailer.backend.DbBackend'
So even when importing from from django.core.mail import send_mail, the send_mail function still queues up the email in the database instead of sending it immediately.
It works just fine when actually running the website, but when testing the website, and accessing some webpages that trigger emails, emails are no longer queued anymore:
def test_something(self):
...
# Check no emails are actually sent yet
self.assertEquals(len(mail.outbox), 0) # test fails here -- 2 != 0
# Check queued emails.
messages = Message.objects.all()
self.assertEquals(messages.count(), 2) # test would also fail here -- 0 != 2
...
How come it doesn't seem to be using the backend when it is testing? (importing send_mail from mailer itself gets the tests to pass, but I can't really change the imports of other mailing apps like django-templated-email)
According to this question django overrides the setting.EMAIL_BACKEND when testing to 'django.core.mail.backends.locmem.EmailBackend'. It's also in the django docs here.
To properly test email with django-mailer, you need to override two settings:
Make the tests to use the django-mailer backend
Make the djano-mailer backend to use the test backend
If you don't set the django-mailer backend (number 2), your tests will try to send the email for real.
You also need to simulate running django-mailer's send_mail management command so that you can check mail.outbox for the correct email.
Here's an example of how to setup a test method:
from mailer.engine import send_all
#override_settings(EMAIL_BACKEND='mailer.backend.DbBackend')
#override_settings(MAILER_EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend')
def test_email(self):
# Code that generates email goes here.
send_all() # Simulates running django-mailer's send_mail management command.
# Code to check the email in mail.outbox goes here.
This strategy makes your tests specific to django-mailer which you don't always want or need. I personally only use this setup when I'm testing specific functionality enabled by django-mailer. Otherwise, I use the default test email backend setup by django.
If you really want have sending of emails (like default) via SMTP in django tests use the decorator:
from django.test.utils import override_settings
#override_settings(EMAIL_BACKEND='django.core.mail.backends.smtp.EmailBackend')
class TestEmailVerification(TestCase):
...
Try the following:
django.core.mail.backends.console.EmailBackend

sending email with sendmail - django

I set up the sendmail email backend with this snippet
I open the shell and run (with actual email accounts):
from django.core.mail import send_mail
send_mail('Subject here', 'Here is the message.', 'from#example.com',
['to#example.com'], fail_silently=False)
After that, the console just prints a:
1
No error messages or anything... but the emails never arrive on the other end...
Is there anything else that I need to configure?
Thanks,
Requested the mail server's error logs from my hosting provider and saw this:
send_to_gateway router failed to expand "${perl{mailtrapheaders2}}":
Undefined subroutine &main::mailtrapheaders2 called.\n`
They are still trying to figure it out :S
In the snippet code:
def send_messages(self, email_messages):
"""
Sends one or more EmailMessage objects and returns the number of email
messages sent.
"""
which returns a variable num_sent which is incremented for every mail that has been actually sent. This is the 1 your are seeing displayed in the console.
Probably the problem is in your mail server. sendmail connects to the mail server and tells him "take this mail and send it to adress X". If the mail server is working it takes is and says OK, and then tries to send it to the address - if something breaks during the send its mail server error and it is not send to Django.
Check your mail server log, I believe you will find the answer of "why is the main not delivered" there.