Django - как перенаправить при отправке почты - PullRequest
0 голосов
/ 27 февраля 2020

Вопрос: можно ли перенаправить страницу при отправке электронного письма. Отправка почты занимает от 5 до 10 секунд. За это время страница ничего не делает. Пользователи могут повторно отправить форму, чтобы вызвать реакцию. Поэтому я подумал, что, может быть, есть способ перенаправить страницу сразу после сохранения объекта вместо перенаправления после отправки письма. Код ниже:

@login_required
def handle_order(request, **kwargs):
    ....
    order = form.save(commit=False)
    order.active = True
    order.save()

    # send email to the user, 5-10 seconds waiting time
    kwargs = {...}
    mail_order_detail(**kwargs)

    return redirect('shopping:show-order', order.ref_number)

Я пытался использовать сигнал post_save, не работает, все еще придется подождать, пока не будет перенаправлен

Ответы [ 4 ]

2 голосов
/ 27 февраля 2020

если отправка почты занимает слишком много времени с вашей настройкой, может быть лучше использовать некую хронологию или фоновую очередь для отправки писем.

например, создайте новую модель для ваших писем, просто вставьте нужную почту отправить в базу данных, а затем создать задание cron, которое запускается раз в минуту и ​​отправляет всю почту, собранную в модели.

1 голос
/ 27 февраля 2020

Кажется хорошей причиной для обновления вашего приложения с помощью asyn c диспетчера задач, такого как Celery. В django приложении есть очень хороший учебник по настройке сельдерея и задаче asyn c отправителя электронной почты. После того, как вы установили сельдерей и запустили его экземпляр - ознакомьтесь с руководством - вы можете написать похожую функцию, подобную следующей:

from celery import shared_task 

from django.core.mail import send_mail

@shared_task
def send_email_task():
    send_mail('Celery Task Worked!',
    'This is proof the task worked!',
    'support@prettyprinted.com',
    ['sasa@be-breathtaking.net'])

    return None

На вашем маршруте django вы можете вызвать asyn c задача, таким образом, вашему пользователю не придется ждать отправки электронного письма для получения ответа http:

from .tasks import send_email_task

def index(request):
    send_email_task.delay()
    return HttpResponse('<h1>EMAIL HAS BEEN SENT WITH CELERY!</h1>')
1 голос
/ 27 февраля 2020

Обычно вместо того, чтобы отправлять электронное письмо во время запроса, вы используете почтовую очередь какого-либо рода: создайте электронное письмо в вашей базе данных или отправьте его в какую-либо внешнюю очередь заданий и получите другую процесс или система на самом деле выполняют отправку почты (и повторную попытку, так как это часто бывает неудачно) по отдельности.

0 голосов
/ 27 февраля 2020

Похоже, вам нужна асинхронная операция! (По крайней мере, это мое предположение, ха)

Теперь то, что я собираюсь предложить, может привести к чрезмерным накладным расходам в вашем проекте (если вы используете это только для одной операции)

Вы можете использовать библиотеку - Celery - для создания асинхронных задач. С Celery вы можете использовать метод apply_async(), чтобы остальная часть кода в вашем представлении могла продолжать выполняться во время отправки почты.

https://hackernoon.com/asynchronous-tasks-with-celery-redis-in-django-3e00d3735686

РЕДАКТИРОВАТЬ: Masklinn решение, вероятно, является более эффективным и экономически эффективным!

...