Django:从图片网址在ImageField中添加图片

98 投票
10 回答
71740 浏览
提问于 2025-04-15 14:09

请原谅我英语说得不好 ;-)

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

class Photo(models.Model):
    image = models.ImageField('Label', upload_to='path/')

我想从一个图片的链接创建一个照片(也就是说,不是在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)

10 个回答

25

结合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的文件下载示例。

34

from myapp.models import Photo
import urllib
from urlparse import urlparse
from django.core.files import File

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

photo = Photo()    # set any other fields, but don't commit to DB (ie. don't save())
name = urlparse(img_url).path.split('/')[-1]
content = urllib.urlretrieve(img_url)

# See also: http://docs.djangoproject.com/en/dev/ref/files/file/
photo.image.save(name, File(open(content[0])), save=True)

这段代码的意思是……

首先,它定义了一个变量,这个变量用来存储一些信息。接着,它会执行一些操作,比如计算、判断或者循环。最后,代码会输出结果,让我们看到运行的结果是什么。

总的来说,这段代码就是在做一些基本的处理,把输入的信息经过一系列的步骤,最后得到我们想要的结果。

如果你对代码的具体细节有疑问,可以逐行分析,看看每一行在做什么,慢慢就能理解了。

101

我刚刚为这个问题创建了一个代码片段,地址是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))

撰写回答