0

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. :)

ripevik
  • 53
  • 3
  • 10
  • In your model, do you plan to have a number of fields for each file, or do you just want to have a single file field in your X object? I have a suggestion, but not certain where you plan to go in regards to that – CoolestNerdIII Mar 29 '18 at 12:00
  • I want to have a single file field that accepts zip file, however, as you pointed out, i will have an image field `image = ImageField()` like so and loop over each of them and save to db. – ripevik Mar 29 '18 at 12:18

1 Answers1

0

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:

  1. You want to keep the zip file
  2. 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.

CoolestNerdIII
  • 770
  • 4
  • 10
  • Instead of creating a new class XImages, should I not be using the same class X and add the extra field "image" and override the save() function to do the task of saving one image file at a time? I still believe there is an even better solution to this. Also, can you state how a background task can be implemented here? Would really appreciate that. – ripevik Mar 29 '18 at 13:47
  • 1
    Does the zipfile have a single image? If so, then just do that. That's why I listed my assumption up front. The problem with overriding the save method is that if there are numerous files, then the save method will prevent the request from completing until the save operation is completed. For a single file, this might be fine, but for hundreds of files, this delay would be quite noticeable. As for the background task, you can use something like [celery](http://www.celeryproject.org/), and then add a hook on post_save to extract the files after the object has been saved. – CoolestNerdIII Mar 29 '18 at 13:52
  • Sounds really fair to me. I will give it a shot and let you know in the thread. Thank you! – ripevik Mar 29 '18 at 13:57