Reputation: 1042
I have created an post api which will upload images and videos for blogs. I can handle multiple images, not a problem there. But I have to send a video as well from the frontend. I have used Filefield for video. I am no expert in apis but what I think is, since the code I have written is synchronous, everything that I have written will be be done at the same time. Now the issue is, if a user wants to upload a very large video for eg 200-500 mb then, the post api call response will be very long. Is there a way I can save the blog post first, return the response and then start uploading the video in the database of live server.
My models:
class Blogposts(models.Model):
blog_title = models.CharField(max_length=100blank=True)
video = models.FileField(upload_to="media",
null= True)
I tried to use django signals, but then again django signals are also synchronous.Everything I stated above might be wrong as well, I am not sure. But how to approach this?? Or should I use django celery??
Upvotes: 3
Views: 2771
Reputation: 2072
DRF already have partial updates. Use that. Meaning, you make a post request for only the non file fields. Make the video field blank true null true.
Once its done successfully, you get back the id of your post in response. Then make a patch request to upload the file.
Your javascript algo can look roughly like this
const handleFormSubmit => (data) {
file = data.video_file;
delete data.video_file;
axios.post('/blogs/', data).then(response => {
updateUiShowCreatedBlogWithVideoUploading();
id = response.id;
fileUploadRequestData = {
file: file
}
axios.patch('/blogs/${id}/', file).then(response => {
updateUiShowCreatedBlogWithVideoUploaded();
});
});
}
But in general, for large files I would directly upload it to an object store (like S3) from the browser and not bother django process. Once it's done, attache the object like in the patch. In this case your model will just a URL field and not FileField.
If that's too much, at-least use django-storages and let the library handle uploading to S3 from your backend.
Upvotes: 2