A few years ago, I developed a web application that basically: It’s possible to create your user, and after logging in, you can create “locations” and upload multiple media (images/videos/documents) to your location.
I used Django Rest Framework on the backend and React on the front-end.
At first, I did not set the “upload_to” of my FileInput field, so, by default, it will upload all media to the media folder.
Let’s say I upload three files. My media folder will look like:
- media - file1.jpg - file2.jpg - file3.jpg
That looks good; It’s working well!
Now, a few years later, with +4k active users and +40k media uploaded, I found an issue: A customer told me the picture she added a few days ago was wrong. There was another picture in place.
After a few hours of debugging, I finally found the issue!
Let’s say I upload another file with the name “file1.jpg”. You would probably expect the server to rename the file to “file1(2).jpg”, right? Even because it happens on every OS! Something like:
- media - file1.jpg - file1(2).jpg <- the new one - file2.jpg - file3.jpg
What was happening there is: The just added “file1.jpg” was overriding the previous “file1.jpg”.
Well, to fix that, I had to change the “upload_to” to use a dynamic folder with the location id and create a migration to move all the current files to its expected folder.
So now my media folder will look to something like this (e.g.):
- media - location_1 - file1.jpg - file2.jpg - location_2 - file3.jpg
For the images that were overridden, I had to find them on the database to see which user uploaded them so I could warn them.
In summary, that was a mistake I did that I lost like two nights to debug and fix (nights, because it’s a side project).
If you enable uploads in your application, try to make it's path or name unique.
It has a lot of ways to do that, and it only depends on your application:
- It can have a folder by user id;
- It can have a folder by the model id;
- You can generate a folder name using UUID;
- You can generate a new name for the file based on the timestamp/UUID (I thought about using this on the beginning, but won’t work because in my case, the file name must keep the original);
That's all folks!
I hope you guys enjoy it, and keep learning!