我正在尝试使用Django和React上传包含其他表单数据的图像。
400个错误请求
第一个API应该创建一个没有图像的新产品,然后第二个API将编辑产品并添加图像。
当我在客户端创建一个产品时,第一个API的状态为200,第二个API的状态为400。
使用FileReader允许浏览器读取图像的URL。
下面是我的代码:
React
export default function Add(){
let [formData , setFormData] = useState({namee: '',price: ''})
let [files , setFiles] = useState(null)
const handleInputChange = (event) => {
const { name , value } = event.target
setFormData({...formData, [name] : value})
}
const handleImageChange = (event) => {
const file = event.target.files[0]
const reader = new FileReader()
reader.addEventListener("load", function() {
console.log(reader.result)
setFiles(reader.result)
})
reader.readAsDataURL(file)
}
const handleSubmit = (event) => {
event.preventDefault()
const { namee, price } = formData
const formDataObj1 = new FormData()
const formDataObj2 = new FormData()
formDataObj1.append('namee', namee)
formDataObj1.append('price', price)
formDataObj2.append('image', files)
if(files){
fetch('http://127.0.0.1:8000/add' ,
{
method: "POST",
body: formDataObj1,
}
)
.then(response => {
if(response.ok){
fetch('http://127.0.0.1:8000/addimage',
{
method: "PUT",
body: formDataObj2,
})
.then(response => {
console.log(response)
if(response.ok){
alert('Your Product has been added :)')
}
else{
console.error('Form submission failed.')
}
})
.catch(error => {
console.log(error)
})
}
else{
console.error('Form submission failed.')
}
})
.catch(error => {
console.log('Form submission failed.' , error)
})
}
else{
console.log('files is empty')
}
}
const imgStyle = {
marginBottom: '10px'
}
return (
<div className="c3">
<div id="info" className="center">
<h1>Product</h1>
<form onSubmit={handleSubmit} >
<div className="txt_field">
<input type="text" name="namee" value={formData.namee} onChange={handleInputChange} required/>
<span></span>
<label>Name</label>
</div>
<div className="txt_field">
<input type="number" name="price" value={formData.price} onChange={handleInputChange} required/>
<span></span>
<label>Price</label>
</div>
<div style={imgStyle}>
<input type="file" name="image" onChange={handleImageChange} required/>
<span></span>
</div>
<input type="submit" value="Confirm" className="ss"/>
</form>
</div>
</div>
)
}
字符串
Django
# views
class AddProduct(generics.CreateAPIView):
serializer_class = ProductSerializer
def post(self , request , format=None):
name = request.data['namee']
price = request.data['price']
Product.objects.create(name=name, price=price)
return Response('product successfuly added', status=status.HTTP_200_OK)
class AddProductImage(APIView):
serializer_class = AddImageProSerializer
parser_classes = ( MultiPartParser, parsers.JSONParser)
def put(self , request ):
product = Product.objects.last()
serializer = AddImageProSerializer(data=request.data , instance = product)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
# model
class Product(models.Model):
name = models.CharField(max_length=200,null=True)
price = models.FloatField(null=True)
digital = models.BooleanField(default=False,null=True,blank=False)
image = models.ImageField(upload_to='images/',null=True,blank=True)
def __str__(self):
return self.name
# serializers
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ['id' , 'name', 'price']
class AddImageProSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ['image']
# urls
urlpatterns = [
path('', views.ProductView.as_view(), name='ProductView'),
path('cart', views.OrderItemView.as_view(), name='OrderItemView'),
path('orders', views.OrderView.as_view(), name='OrderView'),
path('add', views.AddProduct.as_view(), name='Add'),
path('addimage', views.AddProductImage.as_view(), name='Addimage'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
型
1条答案
按热度按时间brjng4g31#
我发现使用httpie之类的东西来测试Django API很有帮助,而不是同时开发和调试两端。这使您可以确认它是否按预期响应。一旦开始工作,你就可以在你的react应用程序中使用httpie的设置了。
我主要使用axios(而不是fetch)与Django模型视图集(而不是API视图)。在这种情况下,如果你的模型有一个FileField或ImageField,Django默认会简单地“处理”上传。
Django期望的是一个多部分的上传,因为你发送的是表单数据和一个文件。**这需要在客户端(fetch或axios)的头中设置,我注意到你没有这样做。如果这不起作用,而您需要更多帮助,请考虑在您已经发布的urls.py、models.py和serializers.pyviews.py。