Django+React项目POST请求400错误 求代码修正方案
Django+React提交用户补充资料返回400 Bad Request问题解决
问题描述
在Django和React项目中,从个人资料页提交用户注册补充信息时,发送POST请求到/add_details/接口返回400 Bad Request错误,服务器日志记录:
[01/Nov/2023 16:26:07] "POST /add_details/ HTTP/1.1" 400 760
原始代码
前端React代码
import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import Select from "react-select"; function AddDetails() { const [formData, setFormData] = useState({ first_name: '', last_name: '', mobile_number: '', services: [], years_of_experience: '', license_certificate: null, min_charge: '', charge_after_one_hour: '', street_name: '', house_number: '', ward: '', panchayath_municipality_corporation: '', taluk: '', district: '', state: '', country: '', }); const [services, setServices] = useState([]); const [selectedServices, setSelectedServices] = useState([]); useEffect(() => { axios .get('http://127.0.0.1:8000/services/') .then((response) => { setServices(response.data.results); }) .catch((error) => { console.error(error); }); }, []); const handleChange = (e) => { const { name, value } = e.target; if (name === 'services') { const selectedServices = Array.from(e.target.selectedOptions, (option) => option.value ); console.log('Selected Services:', selectedServices); setFormData({ ...formData, services: selectedServices, }); } else { setFormData({ ...formData, [name]: value, }); } }; const serviceOptions = services.map((service) => ({ value: service.id, label: service.Title, })); const handleSelectChange = (selectedOptions) => { setSelectedServices(selectedOptions); const selectedServiceIds = selectedOptions.map((option) => option.value); setFormData({ ...formData, services: selectedServiceIds, }); }; const handleFileChange = (e) => { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = (e) => { const fileContent = e.target.result; setFormData({ ...formData, license_certificate: fileContent, }); dataToSend.append('license_certificate', file); }; reader.readAsDataURL(file); } }; const user=JSON.parse(localStorage.getItem('user')) const userId=user.id console.log(userId) const handleSubmit = async () => { const dataToSend = new FormData(); dataToSend.append('first_name', formData.first_name); dataToSend.append('last_name', formData.last_name); dataToSend.append('mobile_number', formData.mobile_number); dataToSend.append('years_of_experience', formData.years_of_experience); dataToSend.append('min_charge', formData.min_charge); dataToSend.append('charge_after_one_hour', formData.charge_after_one_hour); dataToSend.append('street_name', formData.street_name); dataToSend.append('house_number', formData.house_number); dataToSend.append('ward', formData.ward); dataToSend.append('panchayath_municipality_corporation', formData.panchayath_municipality_corporation); dataToSend.append('taluk', formData.taluk); dataToSend.append('district', formData.district); dataToSend.append('state', formData.state); dataToSend.append('country', formData.country); formData.services.forEach((serviceId) => { dataToSend.append('services', serviceId); }); dataToSend.append('userId', userId); if (formData.license_certificate) { dataToSend.append('license_certificate', formData.license_certificate); } try { const response = await axios.post('http://127.0.0.1:8000/add_details/', dataToSend, { headers: { 'Content-Type': 'multipart/form-data', }, }); console.log('User details added successfully'); toast.success('Submitted successfully'); } catch (error) { console.error('Failed to add user details', error); } }; }
后端Django视图代码
class UserDetailsCreate(generics.CreateAPIView): serializer_class = UserDetailsSerializer def perform_create(self, serializer,request): user_id = self.request.data.get('userId') user = get_object_or_404(User, id=user_id) serializer.save(user=user)
修正后的代码
前端React代码(修复文件处理、移除手动Content-Type设置)
import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import Select from "react-select"; function AddDetails() { const [formData, setFormData] = useState({ first_name: '', last_name: '', mobile_number: '', services: [], years_of_experience: '', license_certificate: null, min_charge: '', charge_after_one_hour: '', street_name: '', house_number: '', ward: '', panchayath_municipality_corporation: '', taluk: '', district: '', state: '', country: '', }); const [services, setServices] = useState([]); const [selectedServices, setSelectedServices] = useState([]); useEffect(() => { axios .get('http://127.0.0.1:8000/services/') .then((response) => { setServices(response.data.results); }) .catch((error) => { console.error(error); }); }, []); const handleChange = (e) => { const { name, value } = e.target; if (name === 'services') { const selectedServices = Array.from(e.target.selectedOptions, (option) => option.value ); console.log('Selected Services:', selectedServices); setFormData({ ...formData, services: selectedServices, }); } else { setFormData({ ...formData, [name]: value, }); } }; const serviceOptions = services.map((service) => ({ value: service.id, label: service.Title, })); const handleSelectChange = (selectedOptions) => { setSelectedServices(selectedOptions); const selectedServiceIds = selectedOptions.map((option) => option.value); setFormData({ ...formData, services: selectedServiceIds, }); }; const handleFileChange = (e) => { const file = e.target.files[0]; if (file) { setFormData({ ...formData, license_certificate: file, }); } }; const user=JSON.parse(localStorage.getItem('user')) const userId=user.id console.log(userId) const handleSubmit = async () => { const dataToSend = new FormData(); dataToSend.append('first_name', formData.first_name); dataToSend.append('last_name', formData.last_name); dataToSend.append('mobile_number', formData.mobile_number); dataToSend.append('years_of_experience', formData.years_of_experience); dataToSend.append('min_charge', formData.min_charge); dataToSend.append('charge_after_one_hour', formData.charge_after_one_hour); dataToSend.append('street_name', formData.street_name); dataToSend.append('house_number', formData.house_number); dataToSend.append('ward', formData.ward); dataToSend.append('panchayath_municipality_corporation', formData.panchayath_municipality_corporation); dataToSend.append('taluk', formData.taluk); dataToSend.append('district', formData.district); dataToSend.append('state', formData.state); dataToSend.append('country', formData.country); formData.services.forEach((serviceId) => { dataToSend.append('services', serviceId); }); dataToSend.append('userId', userId); if (formData.license_certificate) { dataToSend.append('license_certificate', formData.license_certificate); } try { const response = await axios.post('http://127.0.0.1:8000/add_details/', dataToSend); console.log('User details added successfully'); toast.success('Submitted successfully'); } catch (error) { console.error('Failed to add user details', error); } }; }
后端Django视图代码(修复perform_create参数错误)
class UserDetailsCreate(generics.CreateAPIView): serializer_class = UserDetailsSerializer def perform_create(self, serializer): user_id = self.request.data.get('userId') user = get_object_or_404(User, id=user_id) serializer.save(user=user)
额外说明
- 确保
UserDetailsSerializer中services字段配置为多对多关系:
class UserDetailsSerializer(serializers.ModelSerializer): services = serializers.PrimaryKeyRelatedField(queryset=Service.objects.all(), many=True) user = serializers.PrimaryKeyRelatedField(read_only=True) class Meta: model = UserDetails fields = '__all__'
- 后端需配置
django-cors-headers允许跨域请求,避免跨域问题。
内容的提问来源于stack exchange,提问作者arif 786
相关产品推荐
相关产品推荐

