Django REST Framework账号删除:验证后调用删除接口是否合理?
账号删除功能的API设计最佳实践
核心结论
不建议让一个API端点调用另一个端点,更合理的方案是将验证逻辑整合到DELETE请求中,或者把验证逻辑抽为公共函数复用,直接在验证通过后执行删除操作。
为什么不建议端点间互相调用?
- 增加不必要的复杂度:内部调用会引入额外的HTTP请求开销,还可能出现网络超时、请求失败等问题,后续排查故障的难度也会提升。
- 违背RESTful设计原则:DELETE请求本身就对应资源的删除操作,将验证与拆分为两个端点,打破了单一职责和资源操作的对应关系。
- 前端多请求风险:前端先调用POST验证再调用DELETE,中间可能出现用户操作中断、重复提交等情况,增加了出错概率。
优化方案
方案1:将验证逻辑整合到DELETE端点
直接在DELETE请求中完成用户名、密码、确认字符串的验证,通过后执行删除。前端只需要发送一次DELETE请求即可完成整个操作。
修改后的DELETE端点代码:
@api_view(['DELETE']) def delete_user(request, id): try: user = User.objects.get(id=id) # 从请求体获取验证信息 current_username_from_request = request.data.get("username") current_password_from_request = request.data.get("password") delete_string_from_request = request.data.get("delete_string") # 验证用户名 if not current_username_from_request or current_username_from_request != user.username: return Response({"message": "username is wrong"}, status=400) # 验证密码 if not current_password_from_request or not compare_hashed_passwords(current_password_from_request, user.password): return Response({"message": "invalid password"}, status=400) # 验证确认字符串 if not delete_string_from_request or delete_string_from_request != "delete": return Response({"message": "invalid confirmation string"}, status=400) # 验证通过,删除用户 user.delete() return Response({"message": "user deleted successfully"}, status=200) except User.DoesNotExist: return Response({"message": "user not found"}, status=404) except Exception as error: return Response({"message": str(error)}, status=500)
前端调用时,直接发送DELETE请求,将用户名、密码、delete字符串放入请求体即可。
方案2:抽离公共验证函数(适用于需要复用验证逻辑的场景)
如果后续有其他业务需要用到相同的用户删除验证逻辑,可以把验证代码抽成独立函数,在需要的地方直接调用:
def validate_user_for_deletion(user, username, password, delete_string): if username != user.username: return "username is wrong" if not compare_hashed_passwords(password, user.password): return "invalid password" if delete_string != "delete": return "invalid confirmation string" return None # 复用验证函数的POST端点(若仍需保留) @api_view(['POST']) def validating_user_information_for_deletion(request, id): try: user = User.objects.get(id=id) username = request.data["username"] password = request.data["password"] delete_string = request.data["delete_string"] error_msg = validate_user_for_deletion(user, username, password, delete_string) if error_msg: return Response({"message": error_msg}, status=400) # 直接执行删除逻辑,而非调用其他端点 user.delete() return Response({"message": "user deleted successfully"}, status=200) except User.DoesNotExist: return Response({"message": "user not found"}, status=404) except Exception as error: return Response({"message": str(error)}, status=500) # 复用验证函数的DELETE端点 @api_view(['DELETE']) def delete_user(request, id): try: user = User.objects.get(id=id) username = request.data.get("username") password = request.data.get("password") delete_string = request.data.get("delete_string") error_msg = validate_user_for_deletion(user, username, password, delete_string) if error_msg: return Response({"message": error_msg}, status=400) user.delete() return Response({"message": "user deleted successfully"}, status=200) except User.DoesNotExist: return Response({"message": "user not found"}, status=404) except Exception as error: return Response({"message": str(error)}, status=500)
额外建议
- 规范HTTP状态码:验证失败返回
400 Bad Request,用户不存在返回404 Not Found,删除成功返回200 OK或204 No Content,帮助前端更精准处理不同场景。 - 加强身份安全:前端存储的用户ID需防止篡改,建议结合JWT等身份验证机制,确保只有用户本人能执行删除操作。
内容的提问来源于stack exchange,提问作者João Vitor Witt
相关产品推荐
相关产品推荐

