如何将Flutter前端应用与Django+MongoDB后端进行关联?
Flutter 与 Django + MongoDB 后端关联指南
一、后端(Django):先搭好可访问的REST API
要让Flutter和Django打通,首先得把Django改成能对外提供数据接口的服务:
- 安装必要依赖
在Django项目根目录执行:
pip install djangorestframework django-cors-headers djongo
djangorestframework:快速构建REST风格的API接口django-cors-headers:解决Flutter调试时的跨域请求限制djongo:让Django支持连接MongoDB(替代默认的SQLite)
- 配置Django settings
修改settings.py:
INSTALLED_APPS = [ # 原有默认应用 'rest_framework', 'corsheaders', # 你的自定义业务应用,比如'book_api' ] MIDDLEWARE = [ # 放在中间件列表最前面 'corsheaders.middleware.CorsMiddleware', # 原有中间件内容 ] # 调试阶段允许所有跨域请求,上线后改为指定域名 CORS_ALLOW_ALL_ORIGINS = True # 配置MongoDB连接 DATABASES = { 'default': { 'ENGINE': 'djongo', 'NAME': '你的MongoDB数据库名', 'CLIENT': { 'host': 'mongodb://localhost:27017' } } }
- 编写API接口逻辑
假设你要操作MongoDB里的Book集合:
- 先在业务应用里写
models.py:
from djongo import models class Book(models.Model): title = models.CharField(max_length=100) author = models.CharField(max_length=50) _id = models.ObjectIdField() class Meta: db_table = 'books'
- 再写
serializers.py,把模型数据转为JSON格式:
from rest_framework import serializers from .models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__'
- 写
views.py提供数据增删改查接口:
from rest_framework import viewsets from .models import Book from .serializers import BookSerializer class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer
- 最后在项目根目录的
urls.py配置API路由:
from django.urls import path, include from rest_framework.routers import DefaultRouter from book_api.views import BookViewSet router = DefaultRouter() router.register(r'books', BookViewSet) urlpatterns = [ # 原有路由 path('api/', include(router.urls)), ]
启动Django服务:python manage.py runserver 0.0.0.0:8000,现在可以通过http://你的本地IP:8000/api/books访问接口。
二、前端(Flutter):调用后端API获取数据
Flutter通过HTTP请求和后端交互,推荐用dio包(比原生http更易用):
- 添加依赖
修改pubspec.yaml:
dependencies: flutter: sdk: flutter dio: ^5.4.0 # 版本号以最新为准
执行flutter pub get安装依赖。
- 封装网络请求服务
在lib目录下新建services/api_service.dart,统一处理后端交互:
import 'package:dio/dio.dart'; class ApiService { final Dio _dio = Dio(); final String baseUrl = 'http://你的本地IP:8000/api/'; // 获取书籍列表 Future<List<dynamic>> getBooks() async { try { final response = await _dio.get('${baseUrl}books/'); return response.data; } catch (e) { throw Exception('获取数据失败: $e'); } } }
注意:这里的你的本地IP要换成你电脑的实际IP(比如192.168.1.100),模拟器/真机才能访问到本地的Django服务。
- 在UI页面调用服务
比如在lib/main.dart里展示后端返回的书籍数据:
import 'package:flutter/material.dart'; import 'services/api_service.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter-Django Demo', home: const BookListPage(), ); } } class BookListPage extends StatefulWidget { const BookListPage({super.key}); @override State<BookListPage> createState() => _BookListPageState(); } class _BookListPageState extends State<BookListPage> { final ApiService _apiService = ApiService(); List<dynamic> _books = []; bool _isLoading = true; @override void initState() { super.initState(); _fetchBooks(); } Future<void> _fetchBooks() async { try { final books = await _apiService.getBooks(); setState(() { _books = books; _isLoading = false; }); } catch (e) { setState(() { _isLoading = false; }); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(e.toString())), ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('书籍列表')), body: _isLoading ? const Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: _books.length, itemBuilder: (context, index) { final book = _books[index]; return ListTile( title: Text(book['title']), subtitle: Text(book['author']), ); }, ), ); } }
三、关键注意事项
- 调试别用
localhost:模拟器/真机无法通过localhost访问电脑上的Django服务,必须用电脑的本地IP。 - 处理异步状态:Flutter里要用
async/await + setState或FutureBuilder处理API请求的异步逻辑,避免UI卡顿。 - 上线前优化:关闭
CORS_ALLOW_ALL_ORIGINS,改为指定允许的域名;添加请求拦截器处理Token验证(如果需要用户登录);完善API请求的错误捕获和提示。
内容的提问来源于stack exchange,提问作者Nithin.vs
相关产品推荐
相关产品推荐

