Login

Reliably create a Django File using the contents of a URL

Author:
acdha
Posted:
January 26, 2010
Language:
Python
Version:
1.1
Score:
3 (after 3 ratings)

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

  1. Template tag - list punctuation for a list of items by shapiromatron 8 months, 3 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 9 months ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 3 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 4 months ago
  5. Help text hyperlinks by sa2812 1 year, 5 months ago

Comments

fish2000 (on March 31, 2010):

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

#

clawlor (on March 16, 2012):

Don't forget that File.save() does not delete any existing data. Use File.delete() if need be.

#

Please login first before commenting.