Django Rest Framework无法让Flutter获取JSON响应的问题排查
问题分析与解决方案
错误原因总结
URL路径不匹配+占位符错误
- Flutter请求硬编码了
/api/Username/items/,其中Username是未替换的占位符,且DRF的URL配置里是<str:username>/workouts/(路径为workouts而非items),同时URL绑定的视图是getWorkout,但你实际用的视图是getItem,完全不匹配。 - 你说直接请求
/api/Ahesham/items/能成功,但贴出的URL配置里根本没有items路径,说明代码存在不一致。
- Flutter请求硬编码了
DRF视图与Serializer错误
- 视图中
get_object_or_404(User, username=request.user):request.user是User实例,不是用户名字符串,若要通过URL参数取用户,应该用kwargs['username']; - 视图里定义了
items=Item.objects.filter(user=user),但序列化时用了serializer = ItemSerializer(workouts, many=True),workouts变量未定义,应为items; - Serializer的
model= Workout与视图中的Item.objects模型不匹配,应为model=Item。
- 视图中
Flutter解析逻辑错误
DRF返回的是数组(List)(比如你直接请求得到的[{...}]),但Flutter代码强行把响应转成Map,还试图读取不存在的data字段,导致decoded['data']为null,触发类型转换错误。
解决步骤
一、修复DRF端问题
修正URL配置
确保路径、视图函数匹配,比如要实现/api/<username>/items/的请求,URL配置应改为:path('<str:username>/items/', views.getItem, name='api_items'),修正视图函数
如果通过URL参数的用户名获取数据:@api_view(['GET']) def getItem(request, username): # 通过URL参数查询对应用户 user = get_object_or_404(User, username=username) items = Item.objects.filter(user=user) # 用定义好的items变量序列化 serializer = ItemSerializer(items, many=True) return Response(serializer.data)如果要求登录用户只能获取自己的数据,去掉URL中的
username参数:@api_view(['GET']) def getItem(request): # 确保用户已登录(后续可添加IsAuthenticated权限) user = request.user items = Item.objects.filter(user=user) serializer = ItemSerializer(items, many=True) return Response(serializer.data)修正Serializer
确保模型与实际操作的一致:class ItemSerializer(serializers.ModelSerializer): user = serializers.CharField(source="user.username", read_only=True) class Meta: model = Item # 替换成实际的Item模型,而非Workout fields = '__all__'
二、修复Flutter端问题
修正请求URL
把占位符Username替换为真实用户名(比如Ahesham),并匹配DRF的路径:final response = await http.get(Uri.parse("http://127.0.0.1:8000/api/Ahesham/items/"));如果是登录用户获取自身数据,URL改为
/api/items/。修正JSON解析逻辑
适配DRF返回的数组格式,同时增加错误处理:import 'dart:convert'; import 'package:http/http.dart' as http; Future<void> main() async { final response = await http.get(Uri.parse("http://127.0.0.1:8000/api/Ahesham/items/")); if (response.statusCode == 200) { // 响应是数组,转成List类型 final decoded = jsonDecode(response.body) as List; // 遍历每个item for (final item in decoded) { final itemMap = item as Map<String, dynamic>; print('名称:${itemMap['name']},用户:${itemMap['user']}'); // 遍历所有键值对 itemMap.forEach((key, value) { print('$key,$value'); }); } } else { // 打印错误信息便于排查 print('请求失败:${response.body}'); } }
三、可选:配置登录权限
如果要求用户必须登录才能访问,修改DRF权限配置:
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ] }
此时Flutter请求需要携带认证信息,比如JWT:
final response = await http.get( Uri.parse("http://127.0.0.1:8000/api/items/"), headers: { 'Authorization': 'Bearer 你的JWT_TOKEN', }, );
内容的提问来源于stack exchange,提问作者A_K
相关产品推荐
相关产品推荐

