Django:从服务器上的现有文件手动创建模型中的图像字段

Posted

技术标签:

【中文标题】Django:从服务器上的现有文件手动创建模型中的图像字段【英文标题】:Django: manually create imagefield in model from existing file on server 【发布时间】:2011-05-14 14:28:13 【问题描述】:

这可要了我的命!

我正在使用 django-filebrowser,我想创建一个画廊应用程序,利用它的上传功能来管理图像。

我有一个画廊模型,它允许用户在服务器上选择或创建一个目录,并将文件上传到该文件夹​​以显示在画廊中。我想自动搜索用户已上传图像并选择的目录,然后为文件夹中的每个图像自动创建 Image 实例。

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

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

问题是 FileBrowser 与 Django 表示图像的方式不同,但我想使用 DJango ImageFields,因为我可以在模板端使用其他应用程序(sorl 缩略图)。

我拥有文件所需的所有数据,即文件名、路径等,我只是无法让 Django 创建 ImageField 的实例,而无需再次实际上传图像。我只是想填充它。

我看到另一个帖子 here 建议如下:

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。

【问题讨论】:

【参考方案1】:

我可能遗漏了一些东西,但这对我有用:

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 进行检查。

【讨论】:

这是正确的答案,接受的答案至少对我来说是错误的。我也得到了不可调用的错误。我的 django 3.2 版。 另一个选项,如果你的二进制内容已经在内存中,是使用django.core.files.base.ContentFile【参考方案2】:

我将此标记为已回答,因为这是执行此操作的正确方法:

from django.core.files import File

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

Programmatically saving image to Django ImageField

【讨论】:

【参考方案3】:

这适用于我在 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)

【讨论】:

以上是关于Django:从服务器上的现有文件手动创建模型中的图像字段的主要内容,如果未能解决你的问题,请参考以下文章

在不破坏现有迁移的情况下重命名 Django 模型

手动从 Django 中的 MySQL 数据库中删除表

Django模型继承:使用现有超类创建子类

django引入现有数据库

Django根据现有数据库建立/更新model

Django 中的模型表被删除