There's no direct way to save the contents of a URL to a Django File field: you're required to use a File instance but those can only safely wrap normal files, not the file-like object returned by urllib2.urlopen. Several examples online use urllib.urlretrieve() which creates a temporary file but performs no error handling without writing a ton of hackish code.
This demonstrates how to create a NamedTemporaryFile, fill it with the URL contents and save it, all using APIs which raise exceptions on errors.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # The file reference must be populated with a django.core.files.File instance
# but File cannot handle file-like objects such as those returned by urlopen -
# see http://code.djangoproject.com/ticket/8501
#
# Since we'd like to get the normal file name collision avoidance, automatic
# location handling, etc. we'll create a django NamedTemporaryFile because the
# default file storage save logic is smart enough to simply move the temporary
# file to the correct location.
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))
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 8 months, 3 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 9 months ago
- Serializer factory with Django Rest Framework by julio 1 year, 3 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 4 months ago
- Help text hyperlinks by sa2812 1 year, 5 months ago
Comments
FYI, using 'delete=True' throws a TypeError under Django 1.1.1 -- NamedTemporaryFile's constructor doesn't expect the keyword.
Take it out and it works fine; great trick otherwise, thanks
#
Don't forget that File.save() does not delete any existing data. Use File.delete() if need be.
#
Please login first before commenting.