Flutter调用Django REST API获取用户详情时遇类型/格式异常
问题分析与解决方案
问题根源
1. 初始_TypeError原因
Django REST Framework默认对ForeignKey字段仅返回关联对象的ID(整数类型),但你的Flutter Note模型中尝试将这个整数传入需要Map<String, dynamic>类型的User.fromJson方法,导致类型不匹配。
2. 后续FormatException原因
大概率是修改API后返回的JSON格式不合法(比如语法错误),或是Flutter模型解析时未处理空值/异常字段。
分步解决
第一步:修正Django API的序列化逻辑
让API返回嵌套的用户信息(而非仅ID),修改Django序列化器:
# Django 序列化器代码 from rest_framework import serializers from .models import Note, CustomUser class UserSerializer(serializers.ModelSerializer): class Meta: model = CustomUser fields = ('username',) # 只返回需要的用户名字段 class NoteSerializer(serializers.ModelSerializer): author = UserSerializer() # 嵌套序列化用户信息 class Meta: model = Note fields = ('id', 'title', 'content', 'author', 'created_at')
修改后API返回的JSON结构会变成:
[ { "id": 1, "title": "Test Note", "content": "Hello World", "author": { "username": "testuser" }, "created_at": "2024-05-20T12:00:00Z" } ]
第二步:修正Flutter模型解析逻辑
匹配API返回的嵌套结构,同时添加异常处理避免格式错误:
// 修正后的User模型 class User { final String username; User({required this.username}); factory User.fromJson(Map<String, dynamic> json) { // 处理空值,避免解析失败 final username = json['username'] as String? ?? 'Unknown User'; return User(username: username); } } // 修正后的Note模型 class Note { final int id; final String title; final String content; final User author; final DateTime createdAt; Note({ required this.id, required this.title, required this.content, required this.author, required this.createdAt, }); factory Note.fromJson(Map<String, dynamic> json) { return Note( id: json['id'] as int, title: json['title'] as String? ?? '', content: json['content'] as String? ?? '', author: User.fromJson(json['author'] as Map<String, dynamic>), createdAt: DateTime.parse(json['created_at'] as String), ); } }
第三步:添加日志排查格式问题
在Flutter数据获取代码中添加日志,方便定位FormatException的具体原因:
Future<List<Note>> fetchNotes() async { try { final response = await http.get(Uri.parse('http://your-api-url/notes/')); if (response.statusCode == 200) { // 打印响应内容,排查JSON格式问题 print('API Response: ${response.body}'); List<dynamic> data = jsonDecode(response.body); return data.map((json) => Note.fromJson(json)).toList(); } else { throw Exception('Failed to load notes: ${response.statusCode}'); } } catch (e) { print('Error details: $e'); rethrow; } }
内容的提问来源于stack exchange,提问作者bello
相关产品推荐
相关产品推荐

