Hello everyone I have a blog platform, the user can add and edit blog. I used Django and Django Rest Framework to build the website, and for the frontend ReactJS. My problem is when I edit blog I couldn't save the changes until I change the image. This is the error when I just update title without change image.
models.py
def upload_path(instance, filename):
return 'img/{filename}'.format(filename=filename)
class Blog(models.Model):
title = models.CharField(max_length=250)
slug = models.SlugField(max_length=250, unique=True, null=True)
content = models.TextField()
published = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='blog_blog')
objects = models.Manager() # default manager
image = models.ImageField(_("Image"), upload_to=upload_path, null=True)
class Meta:
def __str__(self):
return self.title
views.py
class EditBlog(generics.UpdateAPIView):
permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
serializer_class = BlogSerializer
queryset = Blog.objects.all()
in React edit.js
import React, { useState, useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import axiosInstance from '../../../axios';
import WriteCss from '../../../assets/CSSStyle/WriteBlog.module.css';
import { Image } from 'antd';
export function Edit() {
const navigate = useNavigate();
const { id } = useParams();
const initialFormData = Object.freeze({
title: '',
slug: '',
content: '',
});
const [formData, updateFormData] = useState(initialFormData);
const [postimage, setPostImage] = useState(null);
useEffect(() => {
axiosInstance.get('admin/edit/postdetail/' id).then((res) => {
updateFormData({
...formData,
['title']: res.data.title,
['slug']: res.data.slug,
['content']: res.data.content,
['image']: res.data.image,
});
});
}, [updateFormData]);
const handleChange = (e) => {
if ([e.target.name] == 'image') {
setPostImage({
image: e.target.files,
});
console.log("d",e.target.files);
}
else {
updateFormData({
...formData,
[e.target.name]: e.target.value,
});
}
}
const handleSubmit = (e) => {
e.preventDefault();
console.log(formData);
let ss = new FormData();
ss.append('title', formData.title);
ss.append('slug', formData.slug);
ss.append('content', formData.content);
ss.append('image', postimage.image[0]);
axiosInstance.patch(`admin/edit/` id '/', ss, {
headers:{
Authorization: `JWT ${localStorage.getItem('refresh_token')}`
},
},)
.then((res) => {
// navigate('/admin/');
});
};
return (
<>
<div className='container' style={{marginTop:"7.5rem"}}>
<h1 className={WriteCss.h}>Update Your Article</h1>
<form>
<div className='row'>
<div className='col-12 col-md-12 col-lg-12'>
<input
className={WriteCss.writeInput}
placeholder="Type your title ..."
type="text"
autoFocus={true}
id="title"
label="Post Title"
name="title"
autoComplete="title"
value={formData.title}
onChange={handleChange}
/>
<input
className={WriteCss.writeInput}
placeholder="slug will be generated based on title"
id="slug"
label="Post slug"
name="slug"
autoComplete="slug"
value={formData.slug}
onChange={handleChange}
/>
</div>
<div className='row'>
<div className='col-12 col-md-12 col-lg-12'>
<textarea
className={WriteCss.writeText}
placeholder="Type your blog..."
type="text"
id="content"
label="content"
name="content"
autoComplete="content"
value={formData.content}
onChange={handleChange}
/>
</div>
</div>
<Image
src={formData.image}
style={{ width: '200px', height: '200px' }}/>
<input
accept="image/*"
id="post-image"
onChange={handleChange}
name="image"
type="file"/>
<div className='row'>
<div className={`col-12 col-md-12 col-lg-12 ${WriteCss.col}`}>
<button className={WriteCss.writeSubmit} type="submit" onClick={handleSubmit}>
Update
</button>
</div>
</div>
</div>
</form>
</div>
</>
)}
export default Edit
Any hint or guidance will be really helpful for me to complete the project because I have been stuck in it for more than two weeks.
Thanks
CodePudding user response:
The problem is with handleSubmit
, you cannot read the value of postimage
if it is null:
const handleSubmit = (e) => {
e.preventDefault();
console.log(formData);
let ss = new FormData();
ss.append('title', formData.title);
ss.append('slug', formData.slug);
ss.append('content', formData.content);
if (postimage != null) {
ss.append('image', postimage.image[0]);
}
axiosInstance.patch(`admin/edit/` id '/', ss, {
headers:{
Authorization: `JWT ${localStorage.getItem('refresh_token')}`
},
},)
.then((res) => {
// navigate('/admin/');
});
};
Remember to set required=False
for the image
field of BlogSerializer
.