82 python django urllib django-models
请原谅我丑陋的英语;-)
想象一下这个非常简单的模型:
class Photo(models.Model):
image = models.ImageField('Label', upload_to='path/')
Run Code Online (Sandbox Code Playgroud)
我想从图像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)
Run Code Online (Sandbox Code Playgroud)
如果不告诉我,我希望我已经很好地解释了这个问题.
谢谢 :)
编辑:
这可能有效,但我不知道如何转换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)
Run Code Online (Sandbox Code Playgroud)
Chr*_*ams 95
我刚刚为同样的问题创建了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))
Run Code Online (Sandbox Code Playgroud)
pit*_*ess 31
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)
结合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)
Run Code Online (Sandbox Code Playgroud)
Django的ContentFile文档和Requests的文件下载示例中更相关的文档.
ImageField只是一个字符串,一个相对于你的MEDIA_ROOT设置的路径.只需保存文件(您可能希望使用PIL检查它是否为图像)并使用其文件名填充该字段.
因此,它与您的代码的不同之处在于您需要保存urllib.urlopen文件的输出(在媒体位置内),计算路径,将其保存到模型中.
我在 Python 3 上这样做,它应该可以在 Python 2 上进行简单的改编。这是基于我的知识,我正在检索的文件很小。如果你不是,我可能会建议将响应写入文件而不是在内存中缓冲。
需要 BytesIO 是因为 Django 对文件对象调用了 seek(),而 urlopen 响应不支持搜索。您可以将 read() 返回的字节对象传递给 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))
Run Code Online (Sandbox Code Playgroud)
最近我在 python 3 和 Django 3 中使用了以下方法,也许这对其他人来说也可能很有趣。它类似于克里斯·亚当斯的解决方案,但对我来说它不再起作用了。
import urllib.request
from django.core.files.uploadedfile import SimpleUploadedFile
from urllib.parse import urlparse
from demoapp import models
img_url = 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Stack_Overflow_logo.png'
basename = urlparse(img_url).path.split('/')[-1]
tmpfile, _ = urllib.request.urlretrieve(img_url)
new_image = models.ModelWithImageOrFileField()
new_image.title = 'Foo bar'
new_image.file = SimpleUploadedFile(basename, open(tmpfile, "rb").read())
new_image.save()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
54198 次 |
| 最近记录: |