在Django REST Framework中调用视图类as_view()方法时遭遇Request类型不匹配的AssertionError问题,该如何解决?
在Django REST Framework中调用视图类as_view()方法时遭遇Request类型不匹配的AssertionError问题,该如何解决?
嘿,我来帮你捋清楚这个问题,其实你现在的做法有点绕弯路了,咱们直接从根源上解决:
问题出在哪?
你试图在MeCompInfo视图里直接调用ListAccTokenView.as_view()生成的视图函数,还手动构造Request对象,这本身就不符合DRF视图的设计逻辑。DRF的视图是用来处理外部HTTP请求的,不是用来在内部直接调用的,而且你手动转换Request类型的操作反而搞混了Django原生HttpRequest和DRF封装的Request,才导致了这个类型不匹配的断言错误。
另外还要提一句,你原来的ListAccTokenView里还有个小bug:queryset = ErpLinkToken.objects.filter(id=id, comp=comp)这里的id和comp其实是未定义的,你应该用前面拿到的org_id和entity_id才对,不然运行起来也会报错。
正确的解决方案:复用业务逻辑,而不是调用视图
咱们把共享的查询逻辑抽出来,不要直接调用视图,这样既避免了Request的问题,代码也更清晰易维护:
第一步:把查询逻辑抽成独立函数
先写一个单独的函数来处理ErpLinkToken的查询,这样两个视图都能复用:
def get_erp_link_tokens(org_id, entity_id): # 这里修正了变量名的问题,用org_id和entity_id代替未定义的id、comp return ErpLinkToken.objects.filter(id=org_id, comp=entity_id)
第二步:修改ListAccTokenView复用这个函数
让原来的列表视图调用这个独立函数,保持它的功能不变:
class ListAccTokenView(ListAPIView): serializer_class = TokenSerializers def get_queryset(self): org_id = self.kwargs.get('id') entity_id = self.kwargs.get('comp') return get_erp_link_tokens(org_id, entity_id)
第三步:修改MeCompInfo直接使用查询逻辑
现在在MeCompInfo里不需要再调用视图了,直接用刚才的查询函数,然后自己处理序列化:
class MeCompInfo(APIView): def get_comp_info(self, request): # 从url的kwargs里获取需要的参数(和ListAccTokenView的逻辑一致) org_id = self.kwargs.get('id') entity_id = self.kwargs.get('comp') # 直接调用查询函数获取数据 tokens = get_erp_link_tokens(org_id, entity_id) # 用序列化器处理数据,和视图里的逻辑一样 serializer = TokenSerializers(tokens, many=True) token_data = serializer.data # 提取token token = token_data[0]['token'] if token_data else None account_token_client = create_merge_client(token) # 这里处理你需要的organization_data并返回 # 比如根据client获取公司信息,这里根据你的业务逻辑补充 organization_data = ... return organization_data def get(self, request, *args, **kwargs): api_log(msg="Processing GET request...") organization_data = self.get_comp_info(request) # 返回DRF的Response响应 return Response(organization_data)
为什么这个方法更好?
- 彻底避免了Request类型不匹配的问题,因为我们根本不需要再调用视图函数了;
- 代码复用性更强,以后如果查询逻辑需要修改,只改一处就可以;
- 逻辑更清晰,每个组件只做自己的事:视图处理HTTP请求,独立函数处理数据查询。
备注:内容来源于stack exchange,提问作者user3521180
相关产品推荐
相关产品推荐

