2016-05-14 1 views
0

У меня настроен API для отдыха с DRF (Django Rest Framework). Одна из функций API состоит в создании учетной записи пользователя (регистр a.k.a.).Создайте пользователя при отправке задачи в Celery, дайте мне ошибку: пользовательский запрос не существует

После того, как пользователь «создан», я отправляю задание на сельдерей для отправки электронного письма с подтверждением.

Но когда задача выполняется сельдерея работником, произошла ошибка:

DoesNotExist: User matching query does not exist.

Задача принимает идентификатор пользователя и больше ничего. Затем я пытаюсь позвонить в БД. И в этот момент он терпит неудачу.

В данный момент я уверен, что пользователь не создан в базе данных, потому что метод create() завершен.

Если у меня был сон() в моей задаче, он работает.

Так что мой вопрос:

Как я могу убедиться, что мой пользователь создан в БД перед отправкой задания на сельдерей?

Я использую Django 1.9.x

UPDATE 1

tasks.py

@shared_task(name='users.utils.send_activation_email') 
def send_activation_email(url, user_id): 
    try: 
     user = User.objects.get(id=user_id) 
     # ... 
    except User.DoesNotExist: 
     # handle exception 

serializers.py

def create(self, validated_data): 
    user_data = validated_data.pop('user') 
    user = User.objects.create(username=user_data['email'], email=user_data['email'], is_active=False) 
    user.set_password(user_data['password']) 
    user.save() 

    user_profile = user.profile 
    user_profile.language = get_language() or settings.LANGUAGE_CODE 
    user_profile.display_name = validated_data['display_name'] 
    user_profile.save() 
    user_profile.generate_activation_key() 

    request = self.context['request'] 
    url = request.build_absolute_uri(reverse('user_confirm', kwargs={'activation_key': user.profile.activation_key})) 
    send_activation_email.delay(url, user.id) # Celery task 
    subscribe_to_newsletter.delay(user.id, True) # Celery task 

    return user_profile 

UPDATE 2

После рассмотрения моих настроек, я нашел это:

DATABASES = { 
    'default': { 
     'ENGINE': 'django.contrib.gis.db.backends.postgis', 
     'NAME': '*****', 
     'USER': '*****', 
     'PASSWORD': '*****', 
     'HOST': '*****', 
     'PORT': 5432, 
     'ATOMIC_REQUESTS': True, 
    } 
} 

Я отключил ATOMIC_REQUESTS и это сработало!

+0

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

+0

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

+1

@ e4c5 это именно то, что произошло, когда вы сказали, что у меня есть неработающие данные. Просмотрев мой код, я заметил, что в моей конфигурации базы данных был указан ATOMIC_REQUESTS = True. После его удаления он работал как шарм. – Kornikopic

ответ

0

Используйте Джанго сигнал, django.db.models.signals.post_save который посылает сигнал на приемник после приема модели с Save() называется

from django.contrib.auth.models import User 
from django.db.models.signal import post_save 

def create_user_callback(sender, **kwargs): 
    user = kwargs['instance'] 
    if kwargs['created']: 
     #send email to the user 

post_save.connect(create_user_callback, sender=User) 

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

  • Нет связанных вопросов^_^