Django Blog #21: Sending Email

by Alex
Django Blog #21: Sending Email
Sending emails using Django is very easy. First you need a local SMTP server or a certain configuration of the external one in the settings.py file of the project:

  • EMAIL_HOST: SMTP server host, the default is localhost.
  • EMAIL_PORT: SMTP port, default is 25.
  • EMAIL_HOST_USER: The user name of the SMTP server.
  • EMAIL_HOST_PASSWORD: SMTP server password.
  • EMAIL_USE_TLS: Whether to use a secure TLS connection.
  • EMAIL_USE_SSL: Whether to use a secure SSL connection.

If you can’t use an SMTP server, you can set Django to output emails to the shell. This is handy for testing an application without a server. If you need to send emails but don’t have a local SMTP server, you can use an ISP server. The following configuration will work for sending through Gmail with a Google account:

EMAIL_HOST = 'smtp.gmail.com 
EMAIL_HOST_USER = '[email protected]' EMAIL_HOST_PASSWORD = ' your_password ' 
EMAIL_PORT = 587 
EMAIL_USE_TLS = True

Run the python manage.py shell command to open a shell and send emails as follows:

>>> from django.core.mail import send_mail 
>> send_mail('Django mail', 'This e-mail was sent with Django,
'[email protected]', ['[email protected]'], fail_silently=False)

The send_mail() function takes the subject, message, sender, and recipient list as arguments. With the optional fail_silent=False argument, you can make an exception be thrown when a failed attempt to send is made. If the output is 1, then the mail was sent. If a Gmail account will be used, the following item should be activated in the settings at https://myaccount.google.com/lesssecureapps: Now you need to add functionality to the view: Edit the post_share view in the views.py file of the blog application:

from django.core.mail import send_mail 

def post_share(request, post_id)  
   # Get post by id  
    post = get_object_or_404(Post, id=post_id, status='published')  
    sent = False  
   if request.method == 'POST'  
       # The form has been sent   
        form = EmailPostForm(request.POST)  
       if form.is_valid()  
           # Form fields have been validated   
 	    cd = form.cleaned_data   
            post_url = request.build_absolute_uri(post.get_absolute_url())  
            subject = '{} ({}) recommends you read '{}'".format(cd['name'], cd['email'], post.title)  
message = 'Read "{}" at {}nn{}'s comments: {}'.format(post.title, post_url, cd['name'], cd['comments'])
            send_mail(subject, message, '[email protected]', [cd['to']])  
            sent = True  
    else  
        form = EmailPostForm()  
   return render(request, 'blog/post/share.html', {'post': post,   
						   'form': form,   
						    { 'sent': sent})

Declare the sent variable and set it to True when the post is submitted. This variable will be used later in the template to display a message about the successful submission. Since you need to include a link to the post in the email, the get_absolute_url() method will be used to get the absolute path. It will be used as input for request.build_absolute_uri() to build the URL with the HTTP schema and hostname. The subject and body of the email are created based on the cleared data from the submitted form. Finally, the email is sent to the address specified in the to field of the form. When the view is ready, you need to add a new URL template. Open the blog application’s urls.py file and add the post_share URL template:

urlpatterns = [ 
   # .. 
    path('<int:post_id>/share/',
         views.post_share, name='post_share'), 
]

Related Posts

LEAVE A COMMENT