You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Rest Framework无法让Flutter获取JSON响应的问题排查

问题分析与解决方案

错误原因总结

  1. URL路径不匹配+占位符错误

    • Flutter请求硬编码了/api/Username/items/,其中Username是未替换的占位符,且DRF的URL配置里是<str:username>/workouts/(路径为workouts而非items),同时URL绑定的视图是getWorkout,但你实际用的视图是getItem,完全不匹配。
    • 你说直接请求/api/Ahesham/items/能成功,但贴出的URL配置里根本没有items路径,说明代码存在不一致。
  2. 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。
  3. Flutter解析逻辑错误
    DRF返回的是数组(List)(比如你直接请求得到的[{...}]),但Flutter代码强行把响应转成Map,还试图读取不存在的data字段,导致decoded['data']为null,触发类型转换错误。


解决步骤

一、修复DRF端问题

  1. 修正URL配置
    确保路径、视图函数匹配,比如要实现/api/<username>/items/的请求,URL配置应改为:

    path('<str:username>/items/', views.getItem, name='api_items'),
    
  2. 修正视图函数
    如果通过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)
    
  3. 修正Serializer
    确保模型与实际操作的一致:

    class ItemSerializer(serializers.ModelSerializer):
        user = serializers.CharField(source="user.username", read_only=True)
    
        class Meta:
            model = Item  # 替换成实际的Item模型,而非Workout
            fields = '__all__'
    

二、修复Flutter端问题

  1. 修正请求URL
    把占位符Username替换为真实用户名(比如Ahesham),并匹配DRF的路径:

    final response = await http.get(Uri.parse("http://127.0.0.1:8000/api/Ahesham/items/"));
    

    如果是登录用户获取自身数据,URL改为/api/items/。

  2. 修正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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 01:00:58