如何在Flutter中解码并使用Django REST API的详情端点?
Django REST 详情端点在Flutter中的解码与使用方案
1. 确认Django详情端点的响应格式
先确保你的详情端点(比如/api/items/{id}/)返回单个对象的JSON结构,示例如下:
{ "id": 1, "title": "示例商品", "description": "商品详情描述", "created_at": "2024-05-20T14:20:00Z" }
2. 调整Flutter模型类
基于你已有的列表模型,补充单个对象的解析方法:
class Item { final int id; final String title; final String description; final DateTime createdAt; Item({ required this.id, required this.title, required this.description, required this.createdAt, }); // 从单个JSON对象解析为Item实例 factory Item.fromJson(Map<String, dynamic> json) { return Item( id: json['id'], title: json['title'], description: json['description'], createdAt: DateTime.parse(json['created_at']), ); } }
3. 实现详情接口的请求逻辑
使用http包发起GET请求并完成解码:
import 'package:http/http.dart' as http; import 'dart:convert'; Future<Item> fetchItemDetail(int itemId) async { final response = await http.get( Uri.parse('http://你的API域名/api/items/$itemId/'), headers: {'Content-Type': 'application/json'}, ); if (response.statusCode == 200) { // 解码JSON并转为Item对象 return Item.fromJson(jsonDecode(response.body)); } else if (response.statusCode == 404) { throw Exception('该条目不存在'); } else { throw Exception('加载详情失败'); } }
4. 在页面中展示详情数据
用FutureBuilder处理异步请求并渲染UI:
class ItemDetailPage extends StatelessWidget { final int itemId; const ItemDetailPage({super.key, required this.itemId}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('商品详情')), body: FutureBuilder<Item>( future: fetchItemDetail(itemId), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text('错误: ${snapshot.error}')); } else if (snapshot.hasData) { final item = snapshot.data!; return Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(item.title, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), const SizedBox(height: 12), Text(item.description, style: const TextStyle(fontSize: 16)), const SizedBox(height: 12), Text('创建时间: ${item.createdAt.toLocal().toString().split(' ')[0]}'), ], ), ); } return const Center(child: Text('无数据')); }, ), ); } }
5. 关键注意事项
- 测试环境下,Android需在
AndroidManifest.xml添加网络权限:<uses-permission android:name="android.permission.INTERNET"/>;iOS需在Info.plist配置允许HTTP请求(针对非HTTPS的本地API) - 确保Django端点的URL参数(比如
{id})与Flutter请求中的itemId匹配 - 可根据实际需求添加更多错误分支处理(如网络异常、字段缺失)
内容的提问来源于stack exchange,提问作者ismail Ibrahim Abdinur
相关产品推荐
相关产品推荐

