Django开发API报get()参数不匹配与slug路由404问题求解
错误原因及修复方案
1. 核心报错get() takes 1 positional argument but 2 were given的直接诱因
类的实例方法第一个参数必须是实例本身self,你在继承APIView的两个视图类中定义get方法时,漏掉了self参数。DRF调用视图方法时会自动传入self实例作为第一个参数,加上request参数,实际传了2个参数,但你的方法只接收1个,就触发了这个报错。
修正后的views.py代码:
from django.shortcuts import render from rest_framework.response import Response from .models import ReviewData from .models import BuildingData from rest_framework.views import APIView from .serializers import ReviewSerializer from .serializers import BuildingSerializer from django.shortcuts import render, get_object_or_404 class BuildingInfoAPI(APIView): # 新增self作为第一个参数 def get(self, request): queryset = BuildingData.objects.all() serializer = BuildingSerializer(queryset, many=True) return Response(serializer.data) class ReviewListAPI(APIView): # 新增self作为第一个参数,同时接收路由传过来的slug参数 def get(self, request, slug=None): # 如果有slug参数,就过滤对应建筑的评论,否则返回全部 if slug: building = get_object_or_404(BuildingData, slug=slug) queryset = ReviewData.objects.filter(building_name=building.building_name) else: queryset = ReviewData.objects.all() serializer = ReviewSerializer(queryset, many=True) return Response(serializer.data)
2. 带slug参数路由404的关联问题
修复上述get方法参数问题后如果还有404或空数据,需要检查两个隐藏问题:
- 你当前
BuildingData的save方法逻辑错误:现有逻辑中不管是新建还是编辑,只要self.slug不为空就进入第一个分支,你写的创建时的else分支永远不会被触发,因为你给slug字段设置了默认值uuid.uuid1,新建时slug已经有值了。修正后的save方法如下:
def save(self, *args, **kwargs): # 新建或建筑名变更时,重新生成唯一slug if not self.pk or slugify(self.building_name, allow_unicode=True) != self.slug: self.slug = generate_unique_slug(BuildingData, self.building_name) super(BuildingData, self).save(*args, **kwargs)
- 你当前
ReviewData没有和BuildingData做外键关联,用building_name做关联字段的话要保证两边的building_name完全一致,不然过滤的时候会查不到数据。如果需要更稳定的关联查询,可以把之前注释掉的外键字段放开使用。
内容的提问来源于stack exchange,提问作者JYH
相关产品推荐
相关产品推荐

