Flutter中嵌套模型对接Django API:解决类型转换错误
问题解决:Flutter解析Django外键数据时类型不匹配
问题根源
你遇到的_TypeError是因为Django REST Framework默认序列化外键字段时,只会返回关联对象的ID(整数类型),但你的Flutter ShowsModel里期望json['director']是包含导演完整信息的Map<String, dynamic>,两者类型不匹配导致报错。
解决方案
步骤1:修改Django序列化器,返回嵌套的导演数据
在Django的DRF序列化器中,需要配置Show的序列化器,让它返回Director的完整信息,而不是仅ID。
假设你已有serializers.py,修改如下:
from rest_framework import serializers from .models import Director, Show # 定义导演序列化器 class DirectorSerializer(serializers.ModelSerializer): class Meta: model = Director fields = ['id', 'name', 'surname', 'image'] # 按需选择需要返回的字段 # 定义剧集序列化器,嵌套导演数据 class ShowSerializer(serializers.ModelSerializer): # 使用嵌套序列化器关联导演数据 director = DirectorSerializer(read_only=True) class Meta: model = Show fields = ['id', 'name', 'annotation', 'language', 'image', 'director']
也可以用更简便的depth参数替代嵌套序列化器(自动嵌套所有关联对象,灵活性稍弱):
class ShowSerializer(serializers.ModelSerializer): class Meta: model = Show fields = '__all__' depth = 1
修改后重启Django服务,API返回的Show数据中,director字段会是包含导演姓名、姓氏等信息的字典,而非单纯的ID。
步骤2:修复Flutter模型的可空性问题
注意到Django中Show的director、language、image字段均允许为null,Flutter模型需对应设置可空类型,避免无导演的剧集解析报错:
修改ShowsModel:
import 'package:flutter/widgets.dart'; import 'package:kulises_app/models/directors.dart'; class ShowsModel with ChangeNotifier { int id; String name; String annotation; String? language; DirectorModel? director; String? image; ShowsModel({ required this.id, required this.name, required this.annotation, this.language, this.director, this.image, }); factory ShowsModel.fromJson(dynamic json) { return ShowsModel( id: json['id'], director: json['director'] != null ? DirectorModel.fromJson(json['director']) : null, name: json['name'] as String, annotation: json['annotation'] as String, language: json['language'] as String?, image: json['image'] as String?, ); } static List<ShowsModel> showsFromSnapshot(List snapshot) { return snapshot.map((data) { return ShowsModel.fromJson(data); }).toList(); } }
同步修改DirectorModel的image字段为可空:
import 'package:flutter/widgets.dart'; class DirectorModel with ChangeNotifier { final int id; final String name; final String surname; final String? image; DirectorModel({required this.id, required this.name, required this.surname, this.image}); factory DirectorModel.fromJson(dynamic json) { return DirectorModel( id: json['id'], name: json['name'] as String, surname: json['surname'] as String, image: json['image'] as String?, ); } static List<DirectorModel> directorFromSnapshot(List snapshot) { return snapshot.map((data) { return DirectorModel.fromJson(data); }).toList(); } }
步骤3:验证与使用
修改完成后,调用Show的API接口,确认返回的JSON中director字段为嵌套结构:
{ "id": 1, "name": "测试剧集", "annotation": "剧集简介", "language": "中文", "image": null, "director": { "id": 1, "name": "张三", "surname": "张", "image": "/images/director.jpg" } }
此时Flutter端可正常解析数据,在剧集详情页通过showsModel.director?.name和showsModel.director?.surname展示导演的姓名与姓氏。
内容的提问来源于stack exchange,提问作者amyhawks
相关产品推荐
相关产品推荐

