我正在使用Djoser创建身份验证后端。我希望发生以下情况:
- 用户
http://localhost:8000/auth/users/
使用电子邮件、用户名、密码和 re_password 注册 - 用户在输入的电子邮件中收到一封激活电子邮件,其中包含用于激活其帐户的 URL。URL 的格式为:(
<web url>/activate/{uid}/token
例如http://localhost:8000/activate/Mg/apur8c-6100390a061c5ff081235193867f943a
:) - 单击该 URL 会向服务器发送一个 GET 请求,其中视图 (
UserActivationView
) 接收提取的 uid 和令牌并将其自己的请求发送到<web url>/users/activation/{uid}/token
(http://localhost:8000/users/activation/Mg/apur8c-6100390a061c5ff081235193867f943a
)。并返回它从该请求中获得的响应作为其响应。 - 用户帐户被激活。
这是执行上述所有操作的代码:
# Djoser configuration in settings.py
DJOSER = {
'LOGIN_FIELD': 'email',
'PASSWORD_RESET_CONFIRM_URL': 'password-reset/{uid}/{token}',
'USERNAME_RESET_CONFIRM_URL': 'username-reset/{uid}/{token}',
'SEND_ACTIVATION_EMAIL': True,
'ACTIVATION_URL': 'activate/{uid}/{token}',
'SEND_CONFIRMATION_EMAIL': True,
'PASSWORD_CHANGE_EMAIL_CONFIRMATION': True,
'USERNAME_CHANGED_EMAIL_CONFIRMATION': True,
'USER_CREATE_PASSWORD_RETYPE': True,
'SET_PASSWORD_RETYPE': True,
}
# views.py in user app (users/views.py)
from rest_framework.views import APIView
from rest_framework.response import Response
import requests
class UserActivationView(APIView):
def get(self, request, uid, token):
protocol = "https://" if request.is_secure() else "http://"
web_url = protocol + request.get_host()
post_url = web_url + '/auth/users/activation/'
post_data = {'uid': uid, "token": token}
print(f"Sending request to {post_url} with {post_data}")
result = requests.post(post_url, data=post_data) # <<-- causes the server to hang
return Response(result.text)
# users/urls.py
from django.urls import path, include
from .views import UserActivationView
app_name = "users"
urlpatterns = [
path('auth/', include('djoser.urls')),
path('auth/', include('djoser.urls.jwt')),
path('activate/<str:uid>/<str:token>/',
UserActivationView.as_view())
]
# MAIN project urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('chat/', include('frontend.urls')),
path("chat/", include('backend.urls')),
path('api/accounts/', include('backend.urls')),
path('', include('users.urls'))
]
现在,问题出现在第 3 步(result = requests.post(post_url, data=post_data)
在线)。当视图试图发送一个 post 请求时,服务器会挂起相当长的一段时间。CTRL在此期间,当我执行+时它甚至不会停止C。这是我得到的输出(我添加了评论):
HTTP POST /auth/users/ 201 [5.87, 127.0.0.1:56239] ## User registration was successful and email was sent
HTTP GET /activate/Mg/apuvq9-3461158f807a1e054738458bc2372486 301 [0.00, 127.0.0.1:56245] # 301 response while trying to GET the URL sent in the email
Sending request to http://localhost:8000/auth/users/activation/ with {'uid': 'Mg', 'token': 'apuvq9-3461158f807a1e054738458bc2372486'} # My print statement
# A long pause here. Server hangs and then this error appears:
Application instance <Task pending coro=<StaticFilesWrapper.__call__() running at D:\pigeon\venv\lib\site-packages\channels\staticfiles.py:44> wait_for=<Future pending cb=[_chain_future.<locals>._call_check_cancel() at C:\ProgramData\Anaconda3\lib\asyncio\futures.py:348, <TaskWakeupMethWrapper object at 0x000001E3EDE96858>()]>> for connection <WebRequest at 0x1e3edd8a788 method=GET uri=/activate/Mg/apuvq9-3461158f807a1e054738458bc2372486/ clientproto=HTTP/1.1> took too long to shut down and was killed.
Application instance <Task pending coro=<StaticFilesWrapper.__call__() running at D:\pigeon\venv\lib\site-packages\channels\staticfiles.py:44> wait_for=<Future pending cb=[_chain_future.<locals>._call_check_cancel() at C:\ProgramData\Anaconda3\lib\asyncio\futures.py:348, <TaskWakeupMethWrapper object at 0x000001E3EE1067C8>()]>> for connection <WebRequest at 0x1e3edd8a788 method=GET uri=/activate/Mg/apuvq9-3461158f807a1e054738458bc2372486/ clientproto=HTTP/1.1> took too long to shut down and was killed.
Internal Server Error: /activate/Mg/apuvq9-3461158f807a1e054738458bc2372486/
Traceback (most recent call last):
File "D:\pigeon\venv\lib\site-packages\asgiref\sync.py", line 482, in thread_handler
raise exc_info[1]
File "D:\pigeon\venv\lib\site-packages\django\core\handlers\exception.py", line 38, in inner
response = await get_response(request)
File "D:\pigeon\venv\lib\site-packages\django\core\handlers\base.py", line 238, in _get_response_async
)(e, request)
File "D:\pigeon\venv\lib\site-packages\asgiref\sync.py", line 444, in __call__
ret = await asyncio.wait_for(future, timeout=None)
File "C:\ProgramData\Anaconda3\lib\asyncio\tasks.py", line 414, in wait_for
return await fut
concurrent.futures._base.CancelledError
或者,如果我通过 Postman 或单独的 Python 脚本手动发送激活请求,则该请求可以正常工作并且用户被激活:
该问题似乎仅在从视图中向服务器发出请求时出现。我也尝试过result = requests.get('http://localhost:8000/chat')
作为实验,它也导致服务器挂起,而result = requests.get('http://google.com')
不会导致此类问题。
这会挂起我的调试 django 服务器 – Hack_Hut Apr 25 at 11:55
我该如何解决这个问题?
我在用:
- 蟒蛇:3.7.5
- 姜戈:3.2.5
- 左塞尔:2.1.0
- Django 休息框架:3.12.4
- 请求:2.26.0