Reliably create a Django File using the contents of a URL

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.fromdjango.core.filesimportFilefromdjango.core.files.tempimportNamedTemporaryFileimg_temp=NamedTemporaryFile(delete=True)img_temp.write(urllib2.urlopen(url).read())img_temp.flush()im.file.save(img_filename,File(img_temp))