2016-08-22 2 views
0

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

Я создал файл tasks.py:

# -*- coding: utf-8 -*- 
from __future__ import absolute_import 
from .notifications import CustomerNotifications 
from celery import shared_task 

@shared_task 
def prereservation_has_been_confirmed(reservation): 
    CustomerNotifications.prereservation_has_been_confirmed(reservation) 

Метод CustomerNotifications.prereservation_has_been_confirmed(reservation) отправляет по электронной почте клиенту.

Отправка электронной почты, но она все еще ждет, пока не будет отправлено электронное письмо. (вид вызывается AJAX).

Знаете ли вы, что делать?

EDIT

Это как функция вызывается:

@csrf_exempt 
def reservation_confirm(request): 
    if request.method == 'POST': 
     reservation_id = request.POST.get('reservation_id', False) 
     reservation = get_object_or_404(dolava_models.Reservation, id=reservation_id) 
     reservation.confirmed = True 
     reservation.save() 
     tasks.prereservation_has_been_confirmed(reservation) 
     return JsonResponse({}) 
    raise Http404(u'...') 

Я попытался tasks.prereservation_has_been_confirmed.delay(reservation), но он возвращает это соединение было отказано.

SETTINGS.PY - добавлено BROKER_URL = 'django://', 'kombu.transport.django' и перенесено.

# -*- coding: utf-8 -*- 

""" 
Django settings for dolava project. 

Generated by 'django-admin startproject' using Django 1.9.7. 

For more information on this file, see 
https://docs.djangoproject.com/en/1.9/topics/settings/ 

For the full list of settings and their values, see 
https://docs.djangoproject.com/en/1.9/ref/settings/ 
""" 

import os 

# Build paths inside the project like this: os.path.join(BASE_DIR, ...) 
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 


# Quick-start development settings - unsuitable for production 
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ 

# SECURITY WARNING: keep the secret key used in production secret! 
SECRET_KEY = 'secret_key' 

# SECURITY WARNING: don't run with debug turned on in production! 
DEBUG = True 

ALLOWED_HOSTS = [] 


# Application definition 

INSTALLED_APPS = [ 
    'admin_interface', 
    'flat', 
    'colorfield', 
    'django.contrib.admin', 
    'django.contrib.auth', 
    # 'djcelery_email', 

    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
    'dolava_app', 
    # 'constance', 

    # 'constance.backends.database', 
    'solo', 
    'django_extensions', 
    'django_tables2', 
    'django_countries', 
    'kombu.transport.django' 
] 

MIDDLEWARE_CLASSES = [ 
    'django.middleware.security.SecurityMiddleware', 
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.common.CommonMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
    'django.middleware.clickjacking.XFrameOptionsMiddleware', 

] 

ROOT_URLCONF = 'dolava.urls' 

TEMPLATES = [ 
    { 
     'BACKEND': 'django.template.backends.django.DjangoTemplates', 
     'DIRS': [], 
     'APP_DIRS': True, 
     'OPTIONS': { 
      'context_processors': [ 
       'django.template.context_processors.debug', 
       'django.template.context_processors.request', 
       'django.contrib.auth.context_processors.auth', 
       'django.contrib.messages.context_processors.messages', 
       'django.core.context_processors.media', 
      ], 
     }, 
    }, 
] 

WSGI_APPLICATION = 'dolava.wsgi.application' 
BROKER_URL = 'django://' 

# Database 
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases 

DATABASES = { 
    'default': { 
     'ENGINE': 'django.db.backends.sqlite3', 
     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 
    } 
} 


# Password validation 
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators 

AUTH_PASSWORD_VALIDATORS = [ 
    { 
     'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 
    }, 
    { 
     'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 
    }, 
    { 
     'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 
    }, 
    { 
     'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 
    }, 
] 


# Internationalization 
# https://docs.djangoproject.com/en/1.9/topics/i18n/ 

LANGUAGE_CODE = 'en-us' 

TIME_ZONE = 'UTC' 

USE_I18N = True 

USE_L10N = True 

USE_TZ = True 


# Static files (CSS, JavaScript, Images) 
# https://docs.djangoproject.com/en/1.9/howto/static-files/ 

STATIC_URL = '/static/' 
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) 
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static') 

# CELERY_ALWAYS_EAGER = True 
# SMTP SETTINGS 
# EMAIL_BACKEND = 'djcelery_email.backends.CeleryEmailBackend' 
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' 
# EMAIL_BACKEND = "mailer.backend.DbBackend" 
EMAIL_USE_TLS = True 
EMAIL_HOST = 'smtp.gmail.com' 
EMAIL_PORT = 587 
EMAIL_HOST_USER = '[email protected]' 
EMAIL_HOST_PASSWORD = 'pass' 




MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 
MEDIA_URL = '/media/' 
+0

@Alasdair Я добавил вид в нижней части вопроса. –

+1

вы должны использовать delay(). Если он говорит, что соединение было отклонено, то это проблема, которую вы должны решить. У вас есть ваш экземпляр сельдерея? проверьте соединение с вашим брокером. возможно создать еще одну запись с трассировкой стека – pleasedontbelong

+0

@pleasedontbelong У меня не было установленного брокера. Теперь я установил его, и отправка с задержкой не работает, но я не вижу ошибки в консоли. –

ответ

2

[После комментариев] Ваша задача была правильно отправлена ​​брокеру (в базу данных в вашем случае), вы можете, вероятно, проверить, что ваша ожидающая задача есть.

вы ничего не видите в консоли, потому что вы должны запустить работника сельдерея, который будет читать все ожидающие задачи у брокера и будет выполнять их. have you started the worker process? там вы увидите вызовы, которые вызывают, и результаты или трассировка, если что-то не работает

1

Вы не делаете асинхронной вызов prereservation_has_been_confirmed() для того, чтобы задержать выполнение функции использовать prereservation_has_been_confirmed.delay(...)

@csrf_exempt 
def reservation_confirm(request): 
    if request.method == 'POST': 
     reservation_id = request.POST.get('reservation_id', False) 
     reservation = get_object_or_404(dolava_models.Reservation, id=reservation_id) 
     reservation.confirmed = True 
     reservation.save() 

     # change HERE, you are calling your function directly not asynchronously 
     tasks.prereservation_has_been_confirmed(reservation) 
     # change to below 
     # tasks.prereservation_has_been_confirmed.delay(reservation) 
     return JsonResponse({}) 
    raise Http404(u'...') 

Кроме того, вы не настроили сельдерей правильно использовать в Django приложение. См. Django celery first steps

Смежные вопросы