I'm making a django project that lets specific users to:
* first, upload a file with specified file-type;
* second, use that file to perform some calculations; and
* third, provide a derivative file for download.
The user can then view the list of all the files that was uploaded including the files uploaded by other users and choose which files to download or delete.
I made an app to manage the user's accounts and another app (core) for file uploads and calculations. Now I want to store the uploaded file in a specific directory so that I can easily access the file for data retrieval.
I tried doing this:
def file_path_dir(instance, filename):
return 'files/{0}/{1}'.format(instance.id, filename)
class Core(models.Model):
id = models.AutoField(primary_key=True, editable=False)
date_created = models.DateField(auto_now_add=True)
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
csv = models.FileField(upload_to=file_path_dir,
validators=[FileExtensionValidator(allowed_extensions=['csv'])]) # NOT SAFE
Here, I want the file to be uploaded in a directory using the id that will be stored in the database. However, the file was stored in this directory instead - files/None/filename.
I don't know why it says 'None' when I have successfully saved the file in the database (using postgresql). I need help how to solve this or how to properly do this in order for it to work.
Also, I would like to know the safest/ more secure way of validating file extensions.
The file_path_dir
is called before an actual save on the database side happens. And the id
that you are making use of, is not created yet because the save function isn't called yet.
In order to have the id
you need to save the instance and the file in a temporary folder and then move it after you got the id
from the database.
But a better way of doing is using something else instead of the id
. You can use month, day or even year instead and if you really need something unique for each file directory, you can add a unique field like an extra id
or slug and generate it yourself and make use of that.
And for your second question about validating file extensions:
the first step is to check the format which you're already doing and it's usually safe enough depending on the platform. But if you need more security, you can read the file in a safe environment and see if it meets the rules for that type of extension. Or you can use other apps that do that for you and use them in the background.