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

Flutter调用Django筛选API时遇类型转换异常求助

问题描述

基于本地Django Restful API开发Flutter应用,数据库存在嵌套的ShowsModel与DirectorModel。已在Django的views.py中实现通过check_director参数按导演ID筛选剧集的功能,API测试有效,但Flutter端调用时出现type 'String' is not a subtype of type 'int' of 'index'异常。目前能打印正确结果,但异常仍存在,求解决办法。


相关代码

JSON数据结构

[
    {
        "id": 1,
        "name": "Shows name",
        "annotation": "Some long text",
        "image": "/media/images/poster.jpg",
        "director": {
            "id": 2,
            "name": "First name",
            "surname": "Last name",
            "image": "/media/images/portrait.jpg"
        }
    }
]

Django views.py代码

check_director = self.request.query_params.get('check_director', None)
if check_director:
    queryset = queryset.filter(director=check_director)

serializer = ShowsSerializer(queryset, many=True)
return Response(serializer.data)

Flutter API请求代码

static Future<ShowsModel> getShowsByDirector({required String director}) async {
  try {
      var uri = Uri.parse(
        "http://10.0.2.2:8000/showapi?check_director=1", // 应替换为=$id
      );
      var response = await http.get(uri);
      print("response ${jsonDecode(utf8.decode(response.bodyBytes))}");
      var data = jsonDecode((utf8.decode(response.bodyBytes)));
      if (response.statusCode != 200) {
        throw data["message"];
      }
      return ShowsModel.fromJson(data);
    } catch (error) {
      log("an error occured while getting show info $error");
      throw error.toString();
    }
  }

Flutter页面相关代码

class DirectorDetailPage extends StatefulWidget {
  const DirectorDetailPage({Key? key, required this.id}) : super(key: key);
  final String id;
  @override
  State<DirectorDetailPage> createState() => _DirectorDetailPageState();
}

class _DirectorDetailPageState extends State<DirectorDetailPage> {
  DirectorModel? directorModel;
  ShowsModel? showsModel;
  Future<void> getDirectorInfo() async {
    directorModel = await APIHandler.getDirectorsById(id: widget.id);
    setState(() {});
  }

  Future<void> getDirectorShows() async {
    showsModel = await APIHandler.getShowsByDirector();
    setState(() {});
  }

  @override
  void didChangeDependencies() {
    getDirectorInfo();
    getDirectorShows();
    super.didChangeDependencies();
  }

// 显示导演信息的Widget构建代码
// 本容器应显示数据库中的一个剧集名称
 Container(
           margin: const EdgeInsets.only(bottom: 15.0),
           child: showsModel == null
            ? const Center(
             child: CircularProgressIndicator(),
            )
           : Text(showsModel!.name),
          ),

问题原因及解决办法

1. API返回数组而非单个对象

API返回的是数组格式的JSON([]包裹),但Flutter代码尝试用ShowsModel.fromJson(data)将数组解析为单个ShowsModel对象,导致类型不匹配异常。

解决:
修改API请求方法的返回类型为列表,并遍历数组逐个解析:

static Future<List<ShowsModel>> getShowsByDirector({required String director}) async {
  try {
      var uri = Uri.parse(
        "http://10.0.2.2:8000/showapi?check_director=$director", // 传入导演ID参数
      );
      var response = await http.get(uri);
      print("response ${jsonDecode(utf8.decode(response.bodyBytes))}");
      List data = jsonDecode(utf8.decode(response.bodyBytes));
      if (response.statusCode != 200) {
        throw data["message"];
      }
      return data.map((item) => ShowsModel.fromJson(item)).toList();
    } catch (error) {
      log("an error occured while getting show info $error");
      throw error.toString();
    }
  }

2. 页面代码未适配数组数据

页面中showsModel为单个对象类型,无法接收API返回的列表数据。

解决:

  • 修改页面变量类型:
List<ShowsModel>? showsModelList;
  • 更新数据获取方法:
Future<void> getDirectorShows() async {
  showsModelList = await APIHandler.getShowsByDirector(director: widget.id);
  setState(() {});
}
  • 修改展示逻辑(以显示第一个剧集为例):
Container(
  margin: const EdgeInsets.only(bottom: 15.0),
  child: showsModelList == null || showsModelList!.isEmpty
      ? const Center(child: CircularProgressIndicator())
      : Text(showsModelList![0].name),
),

3. 未正确传递导演ID参数

原代码中API请求硬编码了check_director=1,且调用方法时未传入参数,导致请求逻辑错误。

解决:
调用getShowsByDirector时传入widget.id,如上述代码所示。

4. Django参数类型优化(可选)

Django的query_params.get返回字符串类型,而director外键对应int类型,显式转换更稳妥:

if check_director:
    queryset = queryset.filter(director=int(check_director))

内容的提问来源于stack exchange,提问作者amyhawks

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:22:47