Which parts of Django should handle file download, upload and manipulation functionality? "Where should this code live?"
I have a Django app. I want implement the following functionality in the admin interface.
Download Function:
Take some model objects and write them to a file (json, pickle, shelve, whatever)
Zip the file created in step 1, along with some image files
The user downloads the zip file and temp files are deleted
Upload Function:
User upload the file described above
The file is unzipped, the image files are written to the disk and new objects are created to load the data into the database
Which parts of the my Django app are the "correct" parts for me to implement this functionality into?
Edit:
To put it another way: "Where should this code live?"
Edit:
To clarify my question. In the extreme case, all of this could be written one .py file. For example in views.py. This would "work" but probably be "incorrect" from an MVC perspective. My is how to do this "correctly", rather than just how to get this working.
Related
Is there a convention for where to put miscellaneous files which are opened and read by Django views, but which aren't python code or html templates and aren't processed by the temmplate renderer?
(In my case, I have a View which returns an application/excel .xlsx file to the user. It is generated by reading in a "template" xlsx file with lots of tricky formatting and formulae but no data values. Openpyxl is used to insert selected data from the db, and the resulting workbook is saved and sent to the user.)
I would say this might be the media root dir, which itself is called "media", respectively some subdir of it. So in your app this is a subdirectory at <app-dir>/media or maybe /media/xlsx/.
See also here in the documentation: https://docs.djangoproject.com/en/4.1/topics/files/#file-storage
I'm building an app where the user uploads 1-4 files to shiny through fileinput. An issue arrises where, should the user not drag/select multiple files in one go, then the app will not be able to access them. For example, say the user has 4 files saved locally in 4 different folders and they try uploading them one by one, the app will not function. This happens because when the files are uploaded, fileinput creates a dataframe where one column (datapath) contains the path to a temp file which you can then reference in the server. In the documentation it states...
datapath
The path to a temp file that contains the data that was uploaded. This file may be deleted if the user performs another upload operation.
https://shiny.rstudio.com/reference/shiny/1.6.0/fileInput.html
Is there any way around this problem to prevent this datapath being deleted or perhaps find a way to store the temp file so it won't be lost should a user upload another file?
I had considered multiple fileinput boxes but that just makes the app messy.
There is a reproducible example in the example section of the documentation above.
Class X(models.Model):
zip_file = models.FileField()
Now, this zip_file is a zip having any number of images. I want to be able to extract all the images and save (to DB) them under the same X object i.e. the "primary key" is the same.
I understand that the File is stored in the system and only a reference is stored in the DB and I am fine with it.
I am unsure about what is the best practice to unzip the file at the
server and save them one by one to the DB.
One naive idea I have is using the "validators" to check the files and save them to DB but unsure if that is a best practice.
Any help or suggestion is appreciated. :)
There are a few different ways that you can approach this, based on the requirements and number of images that are in the zip file. I am going to make the following assumptions:
You want to keep the zip file
There are an arbitrary number of image files in each zip file
In this case, then you can format your model as below. Once you finish the file upload process, you can trigger a signal or background task to parse the zip file, and for each image file, create a separate object that is related to the zip file through a foreign key. This would allow you to easily grab all of the files without having to create a number of image fields.
[models.py]
class X(models.Model):
zip_file = models.FileField()
class XImages(models.Model):
image = models.ImageField()
x = models.ForeignKey(X)
In the case where you don't actually care about keeping the zip file, then you can do something similar, but instead of saving the object on the form post, you can simply extract it then, and save the images in the separate class.
If there are a static number of images in each zip file, then you can simply create that specific number of ImageFields in the model itself.
I'm new in Django and im trying to achieve what mentioned...but i was not able to get some AudioField or MediaField in Django models, more or less likely ImageField.
Explaining better what i want:
I want to give to the user a form where he can fill with some information and can upload a zip file containing mp3 files. Then, in server i want to get this zip file, unzip it, get all of mp3 inside and get some information about these files (name, artist, duration, etc) and save this in my model (Music).
Is there some tutorial explaining how to achieve that or some links explaining how to work with zip files, and mp3 files?
I think all you need here are the 2 following links:
Python standard library (both 2.x.x and 3.x.x) contains module for work with zip files. https://docs.python.org/3/library/zipfile.html
i.e.:
with ZipFile('music_files.zip') as zip_file:
# get the list of files
names = zip_file.namelist()
# handle your files as you need. You can read the file with:
with zip_file.open(name) as f:
music_file = f.read()
# retrieve music_file metadata here
As for the extraction of mp3 files metadata there is a library: http://eyed3.nicfit.net
Hope it will help you.
The Field you are looking for is the FileField which is agnostic to the type of file it references.
The Python's standard library includes a package to work with Zip archives: zipfile.
You can use the eyeD3 library to extract ID3 metadata from the MP3 files.
HIn Django, when uploading a file with spaces, and brackets, it's stored in the file system with a different filename.
For example, when uploading the file 'lo go (1).jpg' via the admin interface, it's stored on the filesystem as 'lo__go_1.jpg'.
How can I know what the file will be called at upload time? I can't seem to find the source code that replaces the characters.
I found out the answer to my question.
https://github.com/django/django/blob/master/django/db/models/fields/files.py#L310
https://github.com/django/django/blob/master/django/core/files/storage.py#L58
https://github.com/django/django/blob/master/django/utils/text.py#L234