Is there a more faster and efficient ways to send email in django so that the user does not have to wait the entire time the page loads

I am making a website where a user registers to book an instructor for a certain period of time according to a plan he chooses. There are three plans from which a user can choose namely 7days, 14days and 21days. After registering, the user needs to accept an agreement and then based on the plan he has chooses an expiration date is set from the day the user has accepted the agreement.

Now after the user, has accepted the agreement, a copy of the agreement is sent to the user as well as the owners of the website through email. The owners want this system, where the copy of agreement is recieved by both the user and them. I am able to make this happen, and the site is working fine in the testing phase. So basically, two emails are sent after the user accepts and a Contract model is updated.

Now, I have noticed that sending two emails takes a good of time, and the page keeps on loading until both the emails are sent, and then the redirects and all happens for the user. This waiting time may trigger some users to press back interrupting the smtp connection, and then trying to accept the agreement again will raise an intigrity error and also provide a poor user experience. The below code is how making this happen.

views.py (posting only a part where the plan is 7days)


    if request.method == 'POST':
           agreement = Contract()
           
           if request.user.plan == '7days':
                agreement.user = request.user
                agreement.contract_status = True
                expiry = datetime.now() + timedelta(days=7)
                agreement.date_of_acceptance = datetime.now()
                agreement.date_of_expiration = expiry
                agreement.save()
           
                # for the customers
                template = render_to_string('contract_email.html', {'name': request.user.full_name, 'email': request.user.email, 'plan': request.user.plan,'price': 2000, 'accept': agreement.date_of_acceptance, 'expire':agreement.date_of_expiration})
                email = EmailMessage(
                    'Copy of Contract',                                   #subject
                    template,                                                      # body
                    settings.EMAIL_HOST_USER,
                    [request.user.email],                                       # sender email
                )
                email.fail_silently = False
                email.content_subtype = 'html'       # WITHOUT THIS THE HTML WILL GET RENDERED AS PLAIN TEXT
                email.send()

                #for the owners

                template = render_to_string('contract_email.html', {'name': request.user.full_name, 'email': request.user.email, 'plan': request.user.plan,'price': 2000, 'accept': agreement.date_of_acceptance, 'expire':agreement.date_of_expiration})
                email = EmailMessage(
                    'Copy of Customer Contract',                                   #subject
                    template,                                                      # body
                    settings.EMAIL_HOST_USER,
                    ['owner@gmail.com'],                                       # sender email
                )
                email.fail_silently = False
                email.content_subtype = 'html'       # WITHOUT THIS THE HTML WILL GET RENDERED AS PLAIN TEXT
                email.send()

                return redirect('user')

The values generated above are all stored in the model and then sent through the email which is neccesary.

Since, I am begginer I want to know if there is a more efficient and faster way of doing this entire task, so that the user does not have to wait for that long for his redirections and the emails are also sent from the backend.

There is not much you can do with synchronous code, what you need to do is setting up an asynchronous view Async with Django and create worker for your email.

The idea is to have all the tasks that could potentially slow down your server wrap in a asynchronous task, this is use in a lot of case and specifically yours where contracts and emails need to be sent but it should not block the connection or code from executing.

Back to Top