Django Ninja Extra 中为何出现 'TypeError: got multiple values for argument 'request'' 错误?

我正在使用 Django Ninja Extra 编写一个 API 控制器,以下是我的代码:

@api_controller('', tags=['User'], auth=NOT_SET, permissions=[])
class User:
    @http_get('/user/colls', response=List[schemas.UserCollsOut], auth=JWTAuth())
    @paginate(PageNumberPagination, page_size=10)
    def get_user_colls(self, request):
        data = userModels.UserCollection.objects.filter(user=request.auth)
        return data

当我运行这段代码时,出现了如下错误:

TypeError: User.get_user_colls() got multiple values for argument 'request'
---------------------------------
"GET - User[get_user_colls] /api/v1/user/colls" ("User.get_user_colls() got multiple values for argument 'request'",)
User.get_user_colls() got multiple values for argument 'request'
Traceback (most recent call last):
  File "C:\Users\Administrator\PycharmProjects\lmew\venv\lib\site-packages\ninja_extra\operation.py", line 214, in run
    result = self.view_func(request, **ctx.kwargs)
  File "C:\Users\Administrator\PycharmProjects\lmew\venv\lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 97, in as_view
    result = self.route.view_func(
TypeError: User.get_user_colls() got multiple values for argument 'request'
Internal Server Error: /api/v1/user/colls

我不太明白为什么会出现这个错误,request 参数应该只会被传入一次。我尝试查看了 Django Ninja Extra 的文档,但没有找到相关的解决方案。

阅读 602
avatarAI BotBETA

这个错误是因为在方法参数中显式声明了request,而Django Ninja Extra框架内部自动将request作为位置参数传递了两次。具体原因和解决方案如下:

根本原因:

  1. 当使用@http_get装饰器时,Django Ninja Extra会自动将request作为第一个位置参数注入
  2. 但你又显式地在方法参数中声明了request参数
  3. 框架的自动注入和你的显式声明导致同一个参数被传递了两次

解决方案:
移除方法中的request参数,改用self.request访问请求对象:

@http_get('/user/colls', response=List[schemas.UserCollsOut], auth=JWTAuth())
@paginate(PageNumberPagination, page_size=10)
def get_user_colls(self):  # 移除request参数
    data = userModels.UserCollection.objects.filter(user=self.request.auth)
    return data

补充说明:

  • 所有控制器方法都可以通过self.request访问请求对象
  • 当使用@paginate装饰器时,如果要访问分页参数,应该显式声明分页参数而不是请求对象:

    def get_user_colls(self, page: int):
      # 通过page参数访问当前页码
      # 通过self.request访问请求对象
1 个回答
@api_controller('', tags=['User'], auth=NOT_SET, permissions=[])
class User:
    @http_get('/user/colls', response=List[schemas.UserCollsOut], auth=JWTAuth())
    @paginate(PageNumberPagination, page_size=10)
    def get_user_colls(self):  # 移除 request 参数
        # 通过 self.context.request 获取请求对象
        request = self.context.request
        data = userModels.UserCollection.objects.filter(user=request.auth)
        return data

或者:

@api_controller('', tags=['User'], auth=NOT_SET, permissions=[])
class User:
    @paginate(PageNumberPagination, page_size=10)
    @http_get('/user/colls', response=List[schemas.UserCollsOut], auth=JWTAuth())
    def get_user_colls(self, request):
        data = userModels.UserCollection.objects.filter(user=request.auth)
        return data
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题