python中self image,python - Django:从图像u在ImageField中添加图像

python - Django:从图像u在ImageField中添加图像

请原谅我丑陋的英语;-)

想象一下这个非常简单的模型:

class Photo(models.Model):

image = models.ImageField('Label', upload_to='path/')

我想从图像URL创建一个照片(即,不是在django管理站点中手动)。

我想我需要做这样的事情:

from myapp.models import Photo

import urllib

img_url = 'http://www.site.com/image.jpg'

img = urllib.urlopen(img_url)

# Here I need to retrieve the image (as the same way that if I put it in an input from admin site)

photo = Photo.objects.create(image=image)

如果不告诉我,我希望我已经很好地解释了这个问题。

谢谢 :)

编辑:

这可能有效,但我不知道如何将content转换为django文件:

from urlparse import urlparse

import urllib2

from django.core.files import File

photo = Photo()

img_url = 'http://i.ytimg.com/vi/GPpN5YUNDeI/default.jpg'

name = urlparse(img_url).path.split('/')[-1]

content = urllib2.urlopen(img_url).read()

# problem: content must be an instance of File

photo.image.save(name, content, save=True)

6个解决方案

93 votes

我刚刚为同样的问题创建了[http://www.djangosnippets.org/snippets/1890/]。 代码类似于上面的pithyless'回答,除了它使用urllib2.urlopen,因为默认情况下urllib.urlretrieve不执行任何错误处理,因此很容易获得404/500页面的内容而不是你需要的内容。 您可以创建回调功能& 自定义URLOpener子类,但我发现创建自己的临时文件更容易:

from django.core.files import File

from django.core.files.temp import NamedTemporaryFile

img_temp = NamedTemporaryFile(delete=True)

img_temp.write(urllib2.urlopen(url).read())

img_temp.flush()

im.file.save(img_filename, File(img_temp))

Chris Adams answered 2019-05-16T17:18:32Z

30 votes

pithyless answered 2019-05-16T17:18:49Z

5 votes

ImageField只是一个字符串,一个相对于您的urllib.urlopen设置的路径。 只需保存文件(您可能希望使用PIL检查它是否为图像)并使用其文件名填充该字段。

因此,它与您的代码的不同之处在于,您需要将urllib.urlopen的输出保存到文件(在媒体位置内),计算路径,将其保存到模型中。

Oli answered 2019-05-16T17:19:25Z

4 votes

我在Python 3上这样做,它应该适用于Python 2上的简单修改。这是基于我的知识,我正在检索的文件很小。 如果不是,我可能会建议将响应写入文件,而不是在内存中缓冲。

需要BytesIO,因为Django对文件对象调用seek(),而urlopen响应不支持搜索。 您可以将read()返回的bytes对象传递给Django的ContentFile。

from io import BytesIO

from urllib.request import urlopen

from django.core.files import File

# url, filename, model_instance assumed to be provided

response = urlopen(url)

io = BytesIO(response.read())

model_instance.image_field.save(filename, File(io))

jbg answered 2019-05-16T17:19:58Z

4 votes

结合Chris Adams和Stan所说的内容以及更新内容以便在Python 3上工作,如果安装了Requests,您可以执行以下操作:

from urllib.parse import urlparse

import requests

from django.core.files.base import ContentFile

from myapp.models import Photo

img_url = 'http://www.example.com/image.jpg'

name = urlparse(img_url).path.split('/')[-1]

photo = Photo() # set any other fields, but don't commit to DB (ie. don't save())

response = requests.get(img_url)

if response.status_code == 200:

photo.image.save(name, ContentFile(response.content), save=True)

Django的ContentFile文档和Requests的文件下载示例中更相关的文档。

metakermit answered 2019-05-16T17:20:30Z

-3 votes

这是正确和有效的方式

class Product(models.Model):

upload_path = 'media/product'

image = models.ImageField(upload_to=upload_path, null=True, blank=True)

image_url = models.URLField(null=True, blank=True)

def save(self, *args, **kwargs):

if self.image_url:

import urllib, os

from urlparse import urlparse

filename = urlparse(self.image_url).path.split('/')[-1]

urllib.urlretrieve(self.image_url, os.path.join(file_save_dir, filename))

self.image = os.path.join(upload_path, filename)

self.image_url = ''

super(Product, self).save()

Ekin Ertaç answered 2019-05-16T17:20:55Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值