0

I'm trying to send emails asynchronously in Django using asyncio but the below code is not working for me.

async def new(request):
    if request.user.profile.role == 'sa' or request.user.profile.role == 'e':
        if request.method == "GET":
            raise Http404

        elif request.method == "POST":
            form = TaskForm(request.POST)

            if form.is_valid():
                task =form.save()
                
                subject = "New Task"
                message =render_to_string('new_task_email.html', {
                    'task' : task
                })
                user =await sync_to_async(User.objects.get)(id = task.assign_to.id)
                send_mail_async = sync_to_async(user.email_user)
                asyncio.create_task(send_mail_async(subject, message , EMAIL_HOST_USER))

                messages.success(request,"New Task has ceated")
            else:
                messages.warning(request,"Please Enter a valid data")

            return redirect('tasks')
    else:
        raise Http404

but whenever a new task is created and then sending mail to the user getting this error.

SynchronousOnlyOperation at /work_order_panel/tasks/new/
You cannot call this from an async context - use a thread or sync_to_async.

full traceback error

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/work_order_panel/tasks/new/

Django Version: 3.2.6
Python Version: 3.9.6
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'core',
 'user',
 'service',
 'facility',
 'task']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "D:\cmms\env\lib\site-packages\django\contrib\sessions\backends\base.py", line 233, in _get_session
    return self._session_cache

During handling of the above exception ('SessionStore' object has no attribute '_session_cache'), another exception occurred:
  File "D:\cmms\env\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "D:\cmms\env\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "D:\cmms\env\lib\site-packages\asgiref\sync.py", line 223, in __call__
    return call_result.result()
  File "c:\users\maninder singh\appdata\local\programs\python\python39\lib\concurrent\futures\_base.py", line 438, in result
    return self.__get_result()
  File "c:\users\maninder singh\appdata\local\programs\python\python39\lib\concurrent\futures\_base.py", line 390, in __get_result
    raise self._exception
  File "D:\cmms\env\lib\site-packages\asgiref\sync.py", line 292, in main_wrap
    result = await self.awaitable(*args, **kwargs)
  File "D:\cmms\task\views.py", line 46, in new
    if request.user.profile.role == 'sa' or request.user.profile.role == 'e':
  File "D:\cmms\env\lib\site-packages\django\utils\functional.py", line 246, in inner
    self._setup()
  File "D:\cmms\env\lib\site-packages\django\utils\functional.py", line 382, in _setup
    self._wrapped = self._setupfunc()
  File "D:\cmms\env\lib\site-packages\django\contrib\auth\middleware.py", line 23, in <lambda>
    request.user = SimpleLazyObject(lambda: get_user(request))
  File "D:\cmms\env\lib\site-packages\django\contrib\auth\middleware.py", line 11, in get_user
    request._cached_user = auth.get_user(request)
  File "D:\cmms\env\lib\site-packages\django\contrib\auth\__init__.py", line 177, in get_user
    user_id = _get_user_session_key(request)
  File "D:\cmms\env\lib\site-packages\django\contrib\auth\__init__.py", line 60, in _get_user_session_key
    return get_user_model()._meta.pk.to_python(request.session[SESSION_KEY])
  File "D:\cmms\env\lib\site-packages\django\contrib\sessions\backends\base.py", line 65, in __getitem__
    return self._session[key]
  File "D:\cmms\env\lib\site-packages\django\contrib\sessions\backends\base.py", line 238, in _get_session
    self._session_cache = self.load()
  File "D:\cmms\env\lib\site-packages\django\contrib\sessions\backends\db.py", line 43, in load
    s = self._get_session_from_db()
  File "D:\cmms\env\lib\site-packages\django\contrib\sessions\backends\db.py", line 32, in _get_session_from_db
    return self.model.objects.get(
  File "D:\cmms\env\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "D:\cmms\env\lib\site-packages\django\db\models\query.py", line 431, in get
    num = len(clone)
  File "D:\cmms\env\lib\site-packages\django\db\models\query.py", line 262, in __len__
    self._fetch_all()
  File "D:\cmms\env\lib\site-packages\django\db\models\query.py", line 1324, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "D:\cmms\env\lib\site-packages\django\db\models\query.py", line 51, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "D:\cmms\env\lib\site-packages\django\db\models\sql\compiler.py", line 1173, in execute_sql
    cursor = self.connection.cursor()
  File "D:\cmms\env\lib\site-packages\django\utils\asyncio.py", line 24, in inner
    raise SynchronousOnlyOperation(message)

Exception Type: SynchronousOnlyOperation at /work_order_panel/tasks/new/
Exception Value: You cannot call this from an async context - use a thread or sync_to_async.

should I really use sync_to_async when I'm retrieving the user from a database or just use it on user.send_email

Maninder Singh
  • 425
  • 6
  • 14
  • 1
    Can you share the full traceback, where exactly is triggering the error? There are several places in your view that will trigger DB queries, perhaps this view would be better being synchronous? `request.user.profile` and `form.save()` are two places that hit the DB... – Iain Shelvington Aug 25 '21 at 12:20
  • @lain Shelvington I have update the question please look at it – Maninder Singh Aug 25 '21 at 12:31

0 Answers0