Django: 从服务器现有文件手动创建模型中的ImageField

24 投票
3 回答
27137 浏览
提问于 2025-04-16 07:30

这让我很头疼!

我在使用django-filebrowser,想要创建一个图库应用,利用它的上传功能来管理图片。

我有一个图库模型,允许用户选择或创建一个服务器上的文件夹,并将文件上传到那个文件夹中,以便在图库中显示。我希望能够自动扫描用户上传图片的文件夹,然后为文件夹中的每张图片自动创建一个Image实例。

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

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

问题是,FileBrowser对图片的处理方式和Django不一样,但我想用Django的ImageFields,这样我就可以在模板中使用其他应用(比如sorl thumbnails)。

我已经有了文件所需的所有数据,比如文件名、路径等等,只是无法让Django创建一个ImageField的实例,而不需要重新上传图片。我只是想填充这个字段。

我看到另一个讨论 在这里 提到了一些方法:

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())

但是这让我遇到了一个错误:

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

这表明路径没有被正确读取。我打印了文件对象的属性,发现它确实打开了正确的图片,只是没有传递给ImageField。

如果能得到帮助,我会非常感激!

更新

我已经放弃尝试让这个功能正常工作,因为实在是太麻烦了。我之前遇到的问题是,我把ImageField的upload_field设置成了'/',这个问题没有被注意到,导致文件被写入到了'/something.png'。

我已经修改了,现在这个Image使用FileBrowserField而不是ImageField。

3 个回答

2

在Python3和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)
16

我可能漏掉了什么,但这个方法对我有效:

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()

针对下面这个模型:

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

这样做就不行:

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

它显示:

TypeError: 'ImageFieldFile' object is not callable

我在Django 1.7和1.11版本中检查过。

15

我把这个标记为已回答,因为这是正确的做法:

from django.core.files import File

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

通过编程方式将图片保存到Django的ImageField

撰写回答