错误:您的视图返回一个 HttpResponse 对象。相反,它返回了一个未等待的协程。您可能需要在视图中添加“等待”

问题描述 投票:0回答:3

我正在开发一个 Django 项目,其中我将事件添加到数据库,然后在添加事件后向所有订阅者发送电子邮件。我想异步发送电子邮件任务,我遵循了一些博客文章并提出了这个。

from asgiref.sync import sync_to_async
import asyncio

这是添加事件视图

@login_required(login_url='/login/')
async def add_event_view(request):

    if request.method == 'POST':

        title = request.POST.get('title')
        description = request.POST.get('editor')
        menu = request.POST.get('menu')
        tags = request.POST.get('tags')
        banner = request.FILES.get('banner')
        data = request.FILES.get('data', None)
        organised_by = request.POST.get('organised_by', None)
        sponsored_by = request.POST.get('sponsored_by', None)
        event_date = request.POST.get('event_date', None)
        uploaded_at = request.POST.get('uploaded_at')

        Event.objects.create(user_id=request.user, event_title=title, event_description=description, event_category=menu, event_tags=tags,
                             event_banner=banner, event_data=data, organised_by=organised_by, sponsored_by=sponsored_by, event_date=event_date, uploaded_at=uploaded_at)

        await sync_to_async(send_email(title))

        return redirect(etab_view)

这是邮件发送功能

async def send_email(title):

    event = Event.objects.get(event_title=title)

    content = render_to_string("email.html", {'et': event})

    subs = Subscriber.objects.values_list('email_address', flat=True)

    email = EmailMultiAlternatives('Emagazine Update', content, settings.EMAIL_HOST_USER, list(subs))
    email.attach_alternative(content, "text/html")
    email.fail_silenty = False
    email.send()  

我收到以下错误:

视图 EMAG_APP.views.add_event_view 未返回 HttpResponse 对象。相反,它返回了一个未等待的协程。您可能需要在视图中添加“等待”。

有人可以帮我吗?

python django asynchronous async-await
3个回答
11
投票

问题似乎是

login_required
装饰器当前不支持异步视图(请参阅https://code.djangoproject.com/ticket/31949)。该票证中描述的一种解决方案是在装饰器之前包装函数,然后将其解开:

import asyncio

from asgiref.sync import async_to_sync, sync_to_async
from django.contrib.auth.decorators import login_required


@sync_to_async
@login_required(login_url='/login/')
@async_to_sync
async def add_event_view(request):
    ...

0
投票

就我而言,我遇到了此错误,我将其跟踪到以下内容:

class MyView(APIView):
  async def dispatch(req, *args, **kwargs):
     ...
     return super().dispatch(req, *args, **kwargs)

事实证明 super() 方法也是异步的,因此在返回之前需要等待。例如。更改为

return await super()...
修复了它。

当然,此错误的每种情况都会略有不同,但我建议使用调试器进行查看,看看哪个函数调用会触发错误。该函数可能返回一个协程,而应该等待协程并返回其结果。


-1
投票

我认为问题出在

return redirect(etab_view)

etab_view 到底是什么?尝试将其替换为该视图的 urls.py 中给出的名称。

请参阅重定向文档

© www.soinside.com 2019 - 2024. All rights reserved.