You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django用modelform_factory处理DRF POST请求报字段必填错误如何解决

问题根源

你使用DRF的APIView接收JSON格式的POST请求,而Django原生ModelForm默认仅读取request.POST中的表单编码数据,JSON格式的请求体存储在request.data中,你错误地将空的request.POST传入表单,导致表单判定所有字段均未传递,触发必填校验报错。
该报错和是否使用Serializer没有直接关联,核心是参数传入来源错误。

解决方案

方案1:保留现有ModelForm逻辑修改

仅需要调整参数传入位置,同时优化冗余代码即可:

from django.http import JsonResponse
from rest_framework import status
from rest_framework.views import APIView
from django.forms import modelform_factory
from .models import User

# 将表单生成逻辑提到视图外,避免每次请求重复执行
UserForm = modelform_factory(User, fields="__all__")

class UserView(APIView):
    def post(self, request, *args, **kwargs):
        # 传入JSON数据所在的request.data,而非request.POST
        form = UserForm(request.data)
        if form.is_valid():
            form.save()
            return JsonResponse({}, status=status.HTTP_201_CREATED)
        return JsonResponse(form.errors, status=status.HTTP_400_BAD_REQUEST)

方案2:改用DRF原生Serializer(更符合DRF开发规范)

DRF的Serializer原生支持JSON等多种请求格式,适配性和扩展性更强:

  1. 新增serializers.py文件定义序列化器
from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"
  1. 调整视图逻辑
from django.http import JsonResponse
from rest_framework import status
from rest_framework.views import APIView
from .serializers import UserSerializer

class UserView(APIView):
    def post(self, request, *args, **kwargs):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse({}, status=status.HTTP_201_CREATED)
        return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
补充注意事项

Postman发起请求时,需要在Headers中设置Content-Type: application/json,否则DRF无法正常解析JSON格式的请求体。

内容的提问来源于stack exchange,提问作者qwerty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 06:06:03