Flutter向Django后端发送POST请求出现400错误求助
问题:Flutter向Django后端POST请求返回400 Bad Request
Bad Request: /api/homeapi/Users/
[20/Jun/2023 18:16:38] "POST /api/homeapi/Users/ HTTP/1.1" 400 58
以下是相关代码:
serializer.py
from rest_framework import serializers from .models import Brand, User class BrandSerializer(serializers.ModelSerializer): class Meta: model = Brand fields = [ 'imgURL', 'brand_name' ] class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = [ 'email', 'selected_colors' ]
views.py
class BrandViewSet(viewsets.ModelViewSet): queryset = Brand.objects.all() serializer_class = BrandSerializer class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer def create(self, request): serializer = UserSerializer(data=request.data) try: serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) except ValidationError as e: return Response({'errors': e.detail}, status=status.HTTP_400_BAD_REQUEST)
models.py
class Brand(models.Model): imgURL = models.CharField(max_length=120) brand_name = models.CharField(max_length=200) class User(models.Model): email = models.EmailField(max_length=120) selected_colors = models.JSONField()
urls.py
router = routers.DefaultRouter() router.register('Brands', BrandViewSet, basename='brand') router.register('Users', UserViewSet, basename='User') urlpatterns = [ path('admin/', admin.site.urls), path('api/homeapi/', include(router.urls)), path('api/get-csrf-token/', get_csrf_token, name='get-csrf-token'), ]
Flutter端代码
api.dart
import 'package:dio/dio.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; const dataUrl = 'http://127.0.0.1:8000/api/homeapi/Brands/'; Future<void> postData(String url, Map<String, dynamic> fields) async { final headers = {'Content-Type': 'application/json'}; try { final response = await http.post(Uri.parse(url), headers: headers, body: json.encode(fields)); // Convert fields to JSON string if (response.statusCode == 200) { // Request was successful print('POST request successful'); print(response.body); } else { // Request failed print('POST request failed'); } } catch (e) { // Exception occurred during the request print('Error: $e'); } }
register.dart
Future<void> addUserDetails(String email) async { postData(userURL, { "email": email }); }
我实在不知道该怎么办,我尝试加入CSRF Token,但也没有效果。非常感谢任何帮助 :D
问题分析与解决方案
核心原因
返回400错误的直接原因是请求数据不符合序列化验证规则:
- Django的
User模型中,selected_colors是必填的JSONField,但你在Flutter端的请求只传了email字段,缺少这个必填项。 - 你导入了
dio包但实际使用的是http包,这不是当前错误的原因,但可以统一工具包避免混淆。
具体修复步骤
- 补全必填字段
修改Flutter端register.dart的请求数据,加入selected_colors字段:
Future<void> addUserDetails(String email) async { postData(userURL, { "email": email, "selected_colors": [] // 可传空数组或符合业务需求的JSON结构,如["red", "blue"] }); }
- 可选:后端设置字段默认值
如果业务允许selected_colors为空,可以在Django模型中设置默认值,避免前端漏传报错:
# models.py class User(models.Model): email = models.EmailField(max_length=120) selected_colors = models.JSONField(default=list) # 默认空数组
同时更新序列化器,标记该字段为非必填:
# serializer.py class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['email', 'selected_colors'] extra_kwargs = { 'selected_colors': {'required': False} }
- 查看详细错误信息
在Flutter的postData函数中打印响应体,获取Django返回的具体验证错误,方便快速排查:
else { // Request failed print('POST request failed, status code: ${response.statusCode}'); print('Error details: ${response.body}'); // 输出Django返回的验证错误详情 }
- CSRF问题排查(若后续遇到)
如果补全字段后仍有CSRF相关错误,需确保:
- 请求头中携带
X-CSRFToken,可先调用get-csrf-token接口获取token再加入请求头 - Django的
settings.py中配置CORS_ALLOWED_ORIGINS,允许Flutter所在地址(如http://127.0.0.1:5000或模拟器地址)
内容的提问来源于stack exchange,提问作者Lenni
相关产品推荐
相关产品推荐

