How to save a model with FileField using a preexisting file?

3

I'm importing a set of pre-existing Django files, and I'd like to reference them in my templates (which use FileField or ImageField ). For example, one of my templates looks like this:

class Imagem(models.Model):
    arquivo = ImageField(upload_to=u"img/%Y/%m/%d")
    miniatura = ImageField(upload_to=u"img/thumb/%Y/%m/%d")
    ...

And I have several images (already copied to my MEDIA_ROOT ) like this:

MEDIA_ROOT
|- gallery
   |-album1
     |-foto1.jpg
     |-foto2.jpg
     |-...
     |-thumbs
       |-thumbs_foto1.jpg
       |-thumbs_foto2.jpg
       |-...

(Note that the images are not under the folder upload_to , but in another completely different)

Is it possible to create instances of this template by referring to preexisting images without having to make copies of them and without having to rename them and / or move them? And what would be the command to create these instances?

I have no problem navigating the file system, finding the names of the images and associating each image with its thumbnail, my problem is how to create the template itself:

path_imagem = os.path.join(settings.MEDIA_ROOT, 'gallery/album1/foto1.jpg')
path_miniatura = os.path.join(settings.MEDIA_ROOT, 'gallery/album1/thumbs/thumbs_foto1.jpg')
Imagem.objects.create(???)

The examples in the Django documentation (eg FileField , "File Uploads" , Managing Files " ) are all referring to new files, where you create a File or if you get one from an upload, for example. In my case the files already exist and are already under MEDIA_ROOT .

    
asked by anonymous 04.01.2018 / 15:02

1 answer

3

Yes, you can make these references as long as the files are within MEDIA_ROOT . Just pass the relative path as an argument to objects.create :

path_imagem = 'gallery/album1/foto1.jpg'
path_miniatura = 'gallery/album1/thumbs/thumbs_foto1.jpg'
Imagem.objects.create(imagem=path_imagem, miniatura=path_miniatura, ...)

And then the template will refer to the file correctly, disregarding upload_to .

Important detail : If an absolute path is passed instead of a relative path, the method will not work, even though the file is within MEDIA_ROOT !

path_imagem = os.path.join(settings.MEDIA_ROOT, 'gallery/album1/foto1.jpg')
path_miniatura = os.path.join(settings.MEDIA_ROOT, 'gallery/album1/thumbs/thumbs_foto1.jpg')
i = Imagem.objects.create(imagem=path_imagem, miniatura=path_miniatura)

print(i.imagem.path) # /var/www/vhosts/example.com/media/gallery/album1/foto1.jpg
                     # Aparentemente ok, mas...

print(i.imagem.url) # /var/www/vhosts/example.com/media/gallery/album1/foto1.jpg
                    # Deveria ser relativo ao MEDIA_URL, e não ao MEDIA_ROOT, ex.:
                    # /media/gallery/album1/foto1.jpg
                    # https://example.com/media/gallery/album1/foto1.jpg
                    # etc

A relative path is required for the URL to be mounted correctly.

Source: Set an ImageField path in Django manually

    
04.01.2018 / 15:02