DRF报错get() takes 1 positional argument but 2 were given
问题排查与修复方案
直接报错原因
DRF 中APIView的所有请求处理方法(get/post等),除了self之外必须接收request作为第一个固定参数,框架分发请求时会自动把当前请求对象传入该参数。你写的get方法只声明了self参数,调用时多传入了request,因此抛出类型错误。
临时修复该报错只需要修改get方法定义:
# 错误写法 def get(self): # 修正后 def get(self, request):
其他严重逻辑问题修复
仅修改参数后代码依然存在多个会导致线上故障的问题,需要一并修正:
- 全局变量存token存在致命安全问题
你用global token存储前端传入的token是完全错误的实现:全局变量为所有请求共享,多用户并发访问时会出现A用户读取到B用户token的越权问题;如果用户直接访问GET接口、没有先调用POST接口写入token,还会触发变量不存在的报错。
正确的实现逻辑是:前端将token放在请求头中传递,后端直接从请求对象中解析当前用户,不需要单独写接口存储token。 - 类名重名导致冲突
你的视图类和序列化器类都命名为UserDetails,会出现命名空间覆盖,调用时必然报错,需要将序列化器重命名为UserDetailsSerializer。 - 路由配置冗余混乱
两个路由同时指向同一个视图类完全没有必要,存储token的接口属于冗余设计,直接删除即可。
修正后完整代码
视图层 Views.py
from rest_framework.authentication import TokenAuthentication from rest_framework.permissions import IsAuthenticated from rest_framework.views import APIView from rest_framework.response import Response from django.contrib.auth.models import User # 引入重命名后的序列化器 from .serializers import UserDetailsSerializer class UserDetailsView(APIView): # 启用Token认证 authentication_classes = [TokenAuthentication] # 限制只有携带有效token的用户才能访问 permission_classes = [IsAuthenticated] def get(self, request): # 认证通过后request.user直接就是当前登录用户对象,不需要手动查Token表 serializer = UserDetailsSerializer(request.user) return Response(serializer.data)
序列化器 serializers.py
from rest_framework import serializers from django.contrib.auth.models import User class UserDetailsSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('username',)
路由 urls.py
from django.urls import path from . import views urlpatterns = [ path('get-user-details/', views.UserDetailsView.as_view()), ]
前端对接说明
不需要额外调用POST接口上传token,只需要在发起GET请求时,把存在localStorage中的token按照DRF Token认证的规范放在请求头中即可:
Authorization: Token 你存储在localStorage中的token值
配置完成后接口会直接返回当前登录用户的用户名,既不会出现参数错误,也不存在并发安全问题。
内容的提问来源于stack exchange,提问作者Ivan Stepanchuk
相关产品推荐
相关产品推荐

