I’m trying to make simple blog app using django as a backend and react. I’m worikng on making post function. I didn’t have any problem with making simple post with title and description but they have shown up when I tried to add possibility of adding picture to a post.
thats post model:
class Post(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
title = models.CharField(max_length=200, default="no title")
text = models.CharField(max_length=500)
image = models.FileField(upload_to=getImageURL, blank=True, default="no-image.png")
posted = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
api view
@api_view(['POST'])
def MakePost(request):
if request.method == 'POST':
serializer = PostSerializer(data = request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
and my component
export default function MakePost(){
const [userID, setUserID] = useState();
const [text, setText] = useState('');
const [title, setTitle] = useState('');
const [image, setImage] = useState();
const [username, setUsername] = useState(localStorage.username);
(...getting user ID)
const fileSelectedHandler = async event => {
setImage(event.target.files[0]);
console.log(event.target.files[0]);
}
const submit = async e => {
e.preventDefault();
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({author: userID, text: text, title: title, image: image})
}
fetch('http://localhost:8000/api/make-post/', requestOptions)
.then(response => {
console.log(response)
if(response.ok){
return response.json();
}
})
.catch(error => {
console.log(error)
})
}
return(
<div className="Auth-form-container mx-auto w-50 mt-5">
<form className="Auth-form" onSubmit={submit} method="POST" encType="multipart/form-data">
<div className="Auth-form-content">
<h3 className="Auth-form-title">Make new Post</h3>
<div className="form-group mt-3">
<label>Title</label>
<input className="form-control mt-1"
placeholder="Enter text"
name='postDescription'
type='text' value={title}
required
onChange={e => setTitle(e.target.value)}/>
<label>Description</label>
<input className="form-control mt-1"
placeholder="Enter text"
name='postDescription'
type='text' value={text}
required
onChange={e => setText(e.target.value)}/>
</div>
<Form.Group controlId="formFile" className="mb-3">
<Form.Label>Image</Form.Label>
<Form.Control type="file" onChange={fileSelectedHandler} />
</Form.Group>
<div className="d-grid gap-2 mt-3">
<button onClick={submit} className="btn btn-primary">Post</button>
</div>
</div>
</form>
</div>
)
}
How should I approach to that case ? Am I passing image in correct way ? (probably no)
3
Answers
I got rid of
and
passed data like that and it works fine
You can do it either using FormData or encode image to base64 and pass in JSON payload.
Check this.
Convert your fileSelectedHandler function into this
rest keeping other code same, then your backend will be receiving image blob