Django: manually create imagefield in model from existing file on server
Asked Answered
S

3

25

This is killing me!

I'm using django-filebrowser, and I want to create a gallery app that leverages it's upload capabilities to manage images.

I have a Gallery model that allows the user to select or create a directory on the server, and upload files to that folder to appear in the gallery. I want to automatically trawl the directory that the user has uploaded images to and selected, and then automatically create Image instances for each image in the folder.

class Gallery(model.Models):
    gallerydirectory = FileBrowserField(...)
    title = ...
    description ...

class Image(model.Models):
    image_field = models.ImageField()

The problem is that FileBrowser represents images differently to Django, but I want to use DJango ImageFields as I can then use other apps (sorl thumbnails) on the template end.

I have all the data necessary for the file i.e. filename, path etc, I just can't get Django to create an instance of an ImageField, without actually uploading the image again. I simply want to populate it.

I have seen another thread here which suggests the following:

for image in filebrowser_image_objects_list:
    f = File(open('path-to-file-on-server','r'))
    i = Image()
    i.image_field('filename.png',f.read())

but this is giving me a:

SuspiciousOperation error
Attempted access to '/filename.png' denied 

which suggests that the path isn't being read correctly. I've printed the attributes of the File Object, and it is opening the correct image, it just isn't getting passed on to the ImageField

Help would be greately appreciated!

UPDATE

I've given up trying to get this work as it's just too messy. The problem I had above was that I had set the upload_field of the ImageField to '/' and it had gone unnoticed meaning that the file was being written to '/something.png'.

I've modified it so that the Image is now using a FileBrowserField as well instead of an ImageField.

Schwarzwald answered 23/11, 2010 at 16:54 Comment(0)
S
15

I'm marking this as answered, as this is the correct way to do this:

from django.core.files import File

image_model.image_field('path', File().read())

Programmatically saving image to Django ImageField

Schwarzwald answered 1/11, 2011 at 10:11 Comment(1)
Showing error: TypeError: File.__init__() missing 1 required positional argument: 'file'Georgetown
F
15

I might be missing something, but this worked for me:

from a1.models import Model1                                                               
from django.core.files.images import ImageFile
m = Model1.objects.create()                                                                
m.f1 = ImageFile(open("1.png", "rb"))      
m.save()

for the following model:

class Model1(models.Model):                 
    f1 = models.ImageField()

This way it didn't work:

m.f1('1.png', File.read(open('1.png', 'r')))

It says:

TypeError: 'ImageFieldFile' object is not callable

Checked with Django 1.7, 1.11.

Faustofaustus answered 11/9, 2017 at 15:27 Comment(2)
This is the right answer, the accepted answer is giving error for me at least. I also got not callable error. my django version 3.2.Outhe
Another option, if you have the binary content already in memory, is to use django.core.files.base.ContentFile.Emptyhanded
M
2

This works for me on Python3 with Django 2

from urllib.request import urlopen
from urllib.parse import urlparse
from io import BytesIO
from django.core.files.images import ImageFile


from .models import ModelWithImageField

# Solving for SSL Error
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

url = https://www.someurl.com/image.png?other_params_if_they_exist
image_file_name = urlparse(url).path.split('/')[-1]
image_file_content = BytesIO(urlopen(url).read())
ModelWithImageField().image_field.save(image_file_name, image_file_content)
Marabout answered 30/8, 2019 at 19:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.