Vue中使用Axios发送POST请求至Django REST Framework接口时触发django.db.utils.IntegrityError问题排查与解决(新手向)
Vue Axios POST请求到Django REST Framework时触发IntegrityError: NOT NULL constraint failed
我是Web开发新手,当前正尝试在Vue项目中使用Axios向自己基于Django REST Framework搭建的API接口发送POST请求,但每次操作都会触发错误:django.db.utils.IntegrityError: NOT NULL constraint failed: main_checkbox.label。我清楚当前API的构建方式不符合标准规范,但这是另一个问题。目前我可以正常使用Axios发送GET请求,也能通过HTML表单成功发送POST数据,但由于正在开发单页应用(SPA),不希望提交时页面刷新,因此需要采用Axios实现无刷新提交。
我的相关代码:
Vue代码:
<template> <div class="home"> <input type="text" name="label" id="" v-model="label" /> <input type="submit" value="Create" @click="createCheckbox" /> </div> </template> <script> import axios from "axios"; export default { data() { return { label: "", }; }, methods: { async createCheckbox() { let result = axios.post("http://127.0.0.1:8000/create/", { label: this.label, }); console.log(result); }, }, }; </script>
Django视图代码:
from rest_framework.response import Response from rest_framework.decorators import api_view from main.models import checkbox from main.serializers import checkboxSerializer @api_view(['POST']) def create(request): checkboxobj = checkbox.objects.create( state=False, label=request.POST.get('label')) serialized = checkboxSerializer(checkboxobj) return Response(serialized.data)
Django模型代码:
from django.db import models # Create your models here. class checkbox(models.Model): label = models.CharField(max_length=50) state = models.BooleanField(default=False) def __str__(self): return self.label
Django序列化器代码:
from rest_framework.serializers import ModelSerializer from main.models import checkbox class checkboxSerializer(ModelSerializer): class Meta: model = checkbox fields = '__all__'
问题原因分析
你遇到的核心问题是数据格式不匹配:
- Axios默认发送POST请求时,会把数据序列化为JSON格式(
Content-Type: application/json); - 而Django的
request.POST只能解析表单编码格式的数据(Content-Type: application/x-www-form-urlencoded),这也是HTML表单默认的提交格式。
所以当你用Axios发JSON数据时,request.POST.get('label')根本拿不到值,导致label字段为NULL,触发了数据库的非空约束,从而抛出错误。
解决方案
方法一:修改Django视图(推荐,符合DRF规范)
Django REST Framework提供了request.data属性,它可以自动解析JSON、表单编码等多种格式的请求数据,完全适配Axios的默认发送方式。只需要把视图里的request.POST改成request.data即可:
from rest_framework.response import Response from rest_framework.decorators import api_view from main.models import checkbox from main.serializers import checkboxSerializer @api_view(['POST']) def create(request): # 改用DRF的request.data获取请求数据 checkboxobj = checkbox.objects.create( state=False, label=request.data.get('label')) serialized = checkboxSerializer(checkboxobj) return Response(serialized.data)
方法二:修改Axios请求为表单编码格式
如果你坚持要用request.POST,可以让Axios发送表单编码格式的数据:
方式1:使用URLSearchParams
async createCheckbox() { try { const formData = new URLSearchParams(); formData.append('label', this.label); let result = await axios.post("http://127.0.0.1:8000/create/", formData); console.log(result); this.label = ''; // 提交成功后清空输入框 } catch (err) { console.error('提交失败:', err); } }
方式2:使用qs库序列化(需要先安装qs)
npm install qs
然后修改Vue代码:
import axios from "axios"; import qs from 'qs'; export default { // ... methods: { async createCheckbox() { try { let result = await axios.post( "http://127.0.0.1:8000/create/", qs.stringify({ label: this.label }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } ); console.log(result); this.label = ''; } catch (err) { console.error('提交失败:', err); } }, }, };
额外优化建议
- 在Vue的
createCheckbox方法中加上await,并包裹try-catch,这样能正确处理异步请求的结果和错误; - 提交成功后清空输入框,提升用户体验;
- 长远来看,建议使用DRF的序列化器来验证和创建数据,而不是直接用
objects.create,这样能更好地处理数据校验和错误反馈,比如:
@api_view(['POST']) def create(request): serializer = checkboxSerializer(data=request.data) if serializer.is_valid(): serializer.save(state=False) # 这里可以指定默认的state值 return Response(serializer.data) return Response(serializer.errors, status=400)
内容的提问来源于stack exchange,提问作者samyarkhafan
相关产品推荐
相关产品推荐

