我的 Django Rest Framework (DRF) 应用程序遇到了一种情况,其中客户端移动应用程序正在调用我的一个端点并收到 400 错误,但我无法调试出了什么问题。这是日志中显示的内容:
Sep 02 11:11:29 myapp heroku/router at=info method=POST path="/users/generate_otp/?device_token=cBB2x2Y2L04qpQCbYukR31%3AAPA91bEHqCZ3ztI9wim0EzxVZ1Nv6clZMfsDxw7_6reWIVkm5dQcxuWlifnfxkn7Ope_2wTM75_TMw6BV-pAZyEYdrICz1dsk2gX6_aYJwz0-H3SDR2vLWvceiioUs21dTwXQIMwmBN1&mobile=%2B13104014335&device_type=ios" host=myhost.com request_id=fad10208-c01d-4f64-9640-1aff889ab3ee fwd="66.246.86.216" dyno=web.1 connect=0ms service=1ms status=400 bytes=28 protocol=https
如果我通过 Postman 发送相同的 URL,端点将成功返回:
Sep 02 11:41:48 myapp heroku/router at=info method=POST path="/users/generate_otp/?device_token=cKY2x2Y2L04qpQCbYukR31%3AAPA91bEHqCZ3ztI9wim0EzxVZ1Nv6clZMfsDxw7_6reWIVkm5dQcxuWlifnfxkn7Ope_2wTM75_TMw6BV-pAZyEYdrICz1dsk2gX6_aYJwz0-H3SDR2vLWvceiioUs21dTwXQIMwmBN1&mobile=%2B13104014335&device_type=ios" host=myhost.com request_id=4ddabe5f-619d-4665-aff5-28afb9ac277d fwd="66.246.86.216" dyno=web.1 connect=0ms service=572ms status=200 bytes=1686 protocol=https
我尝试通过将这些作为端点的第一行来检查传入的请求:
@action(detail=False, methods=["POST"])
def generate_otp(self, request):
"""
Text a one-time password to the given mobile number to login.
If there's not yet a user with that number, register them.
"""
print("IN GENERATE OTP", flush=True)
print("IN GENERATE OTP, request.data =", request.data, flush=True)
print("IN GENERATE OTP, request.headers =", request.headers, flush=True)
但是这些打印语句永远不会被调用——所以就好像它根本没有进入端点一样。 u2028为了尝试进一步调试请求中发送的内容,我添加了这个中间件:
class RequestLoggingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
print("--- RequestLoggingMiddleware ---")
print(request.method, request.path)
print(request.GET)
print(request.POST)
print(request.body)
print("--------------------------------", flush=True)
response = self.get_response(request)
return response
但再次没有打印任何内容。
我还在settings.py中设置了
DEBUG = True
,甚至添加了:
logger = logging.getLogger("django.request")
logger.setLevel(logging.DEBUG)
所有这些都是试图获取更多信息,了解如何在 POST 请求中收到 400 错误,而该请求似乎在其他地方都适用。让事情变得更加复杂的是,其他人正在运行客户端移动应用程序,但看不到这些结果。
可能发生了什么?在输入端点之前什么情况可能会出现 400 错误?我该如何调试和修复这个问题?
Django 在很多情况下可能会返回 400 Bad 请求。这里有一些提示:
device_token=cBB2x2Y...
,另一者有 device_token=cKY2x2Y...
settings.LOGGING
dict 来执行。配置 django
而不是 django.request
记录器,以确保记录任何错误,而不仅仅是来自 django.request
模块的错误。此配置可能过于冗长,但可能有助于确定框架的哪一部分失败。示例: LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': { ... },
'loggers': {
'django': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': True,
},
},
}