Добавил асинхронную отправку заказов

This commit is contained in:
NikDizell 2026-06-17 18:33:57 +03:00
parent a4d1c9f4b7
commit 8bde7db28a
5 changed files with 114 additions and 9 deletions

View File

@ -70,6 +70,13 @@ if not DEBUG:
LANGUAGE_COOKIE_HTTPONLY = True
LANGUAGE_COOKIE_SAMESITE = 'Lax'
# Redis
CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL', 'redis://localhost:6379/0')
CELERY_RESULT_BACKEND = os.environ.get('CELERY_RESULT_BACKEND', 'redis://localhost:6379/0')
if DEBUG:
A = True
CSRF_TRUSTED_ORIGINS = [
'https://nikdizell.ru',
'https://www.nikdizell.ru',
@ -95,6 +102,7 @@ INSTALLED_APPS = [
'captcha',
'turnstile',
'products',
'background_task',
]
MIDDLEWARE = [
@ -288,5 +296,5 @@ CAPTCHA_LENGTH = 6
CAPTCHA_FONT_SIZE = 30
CAPTCHA_IMAGE_SIZE = (150, 50)
TURNSTILE_SITEKEY = '0x4AAAAAAC12NGPpc4TutFWA'
TURNSTILE_SECRET = '0x4AAAAAAC12NCpzKHKE09JaXRDv0smrSAU'
TURNSTILE_SITEKEY = os.getenv('TURNSTILE_SITEKEY')
TURNSTILE_SECRET = os.getenv('TURNSTILE_SECRET')

View File

@ -7,7 +7,7 @@ from programmer.forms import CallbackForm
from .forms import OrderForm
from django.contrib import messages
from django.shortcuts import redirect
from programmer.utils.email_notifications import send_order_notification
from programmer.utils.email_notifications import send_order_notification, send_order_notification_async
class ProductListView(MenuContextMixin, BreadcrumbMixin, ListView):
@ -155,10 +155,11 @@ def order_create(request, slug):
order.save()
# Сохраняем выбранную конфигурацию (уже сохранена в форме)
success = send_order_notification(order)
if success:
order.notification_sent = True
order.save(update_fields=['notification_sent'])
# success = send_order_notification(order)
# if success:
# order.notification_sent = True
# order.save(update_fields=['notification_sent'])
send_order_notification_async(order)
messages.success(request, '✅ Ваш заказ принят! Мы свяжемся с вами в ближайшее время.')
return redirect('products:product_detail', slug=slug)

View File

@ -252,4 +252,43 @@ def send_test_order_email():
return True
except Exception as e:
logger.error(f"Test order email failed: {e}")
return False
return False
# Асинхронная отправка
def send_order_notification_async(order):
"""Выбирает способ отправки в зависимости от DEBUG."""
if settings.DEBUG:
# Используем background-tasks
from .tasks import send_order_notification_background
send_order_notification_background(order.id)
return True # задача поставлена в очередь
else:
# Используем Celery
try:
from .tasks import send_order_notification_celery
send_order_notification_celery.delay(order.id)
return True
except (ImportError, AttributeError):
# fallback на синхронную отправку
from .email_notifications import send_order_notification
return send_order_notification(order)
def send_multiple_order_notifications_async(orders):
if settings.DEBUG:
from .tasks import send_multiple_order_notifications_background
order_ids = list(orders.values_list('id', flat=True))
send_multiple_order_notifications_background(order_ids)
return len(order_ids)
else:
try:
from .tasks import send_multiple_order_notifications_celery
order_ids = list(orders.values_list('id', flat=True))
send_multiple_order_notifications_celery.delay(order_ids)
return len(order_ids)
except (ImportError, AttributeError):
from .email_notifications import send_multiple_order_notifications
return send_multiple_order_notifications(orders)

56
programmer/utils/tasks.py Normal file
View File

@ -0,0 +1,56 @@
from background_task import background
from django.conf import settings
import logging
logger = logging.getLogger(__name__)
@background(schedule=0)
def send_order_notification_background(order_id):
"""Асинхронная отправка уведомлений о заказе через background-tasks."""
from .email_notifications import send_order_notification
from products.models import Order
try:
order = Order.objects.select_related('product', 'configuration').get(id=order_id)
success = send_order_notification(order)
if success:
order.notification_sent = True
order.save(update_fields=['notification_sent'])
return success
except Order.DoesNotExist:
logger.error(f"Order #{order_id} not found")
return False
@background(schedule=0)
def send_multiple_order_notifications_background(order_ids):
"""Отправка уведомлений для нескольких заказов."""
from .email_notifications import send_multiple_order_notifications
from products.models import Order
orders = Order.objects.filter(id__in=order_ids)
return send_multiple_order_notifications(orders)
try:
from celery import shared_task
except ImportError:
shared_task = None
if shared_task is not None:
@shared_task
def send_order_notification_celery(order_id):
from .email_notifications import send_order_notification
from products.models import Order
try:
order = Order.objects.select_related('product', 'configuration').get(id=order_id)
success = send_order_notification(order)
if success:
order.notification_sent = True
order.save(update_fields=['notification_sent'])
return success
except Order.DoesNotExist:
return False
@shared_task
def send_multiple_order_notifications_celery(order_ids):
from .email_notifications import send_multiple_order_notifications
from products.models import Order
orders = Order.objects.filter(id__in=order_ids)
return send_multiple_order_notifications(orders)

View File

@ -10,4 +10,5 @@ django-taggit
django_ckeditor_5
django-allauth
django-simple-captcha
django-turnstile
django-turnstile
celery