New in version 0.4.
GridFS support comes in the form of the FileField field object. This field acts as a file-like object and provides a couple of different ways of inserting and retrieving data. Arbitrary metadata such as content type can also be stored alongside the files. In the following example, a document is created to store details about animals, including a photo:
class Animal(Document):
genus = StringField()
family = StringField()
photo = FileField()
marmot = Animal('Marmota', 'Sciuridae')
marmot_photo = open('marmot.jpg', 'r') # Retrieve a photo from disk
marmot.photo = marmot_photo # Store photo in the document
marmot.photo.content_type = 'image/jpeg' # Store metadata
marmot.save()
Another way of writing to a FileField is to use the put() method. This allows for metadata to be stored in the same call as the file:
marmot.photo.put(marmot_photo, content_type='image/jpeg')
marmot.save()
So using the FileField is just like using any other field. The file can also be retrieved just as easily:
marmot = Animal.objects(genus='Marmota').first()
photo = marmot.photo.read()
content_type = marmot.photo.content_type
Streaming data into a FileField is achieved in a slightly different manner. First, a new file must be created by calling the new_file() method. Data can then be written using write():
marmot.photo.new_file()
marmot.photo.write('some_image_data')
marmot.photo.write('some_more_image_data')
marmot.photo.close()
marmot.photo.save()
Deleting stored files is achieved with the delete() method:
marmot.photo.delete()
Note
The FileField in a Document actually only stores the ID of a file in a separate GridFS collection. This means that Animal.drop_collection() will not delete any files. Care should be taken to manually remove associated files before dropping a collection.
Files can be replaced with the replace() method. This works just like the put() method so even metadata can (and should) be replaced:
another_marmot = open('another_marmot.png', 'r')
marmot.photo.replace(another_marmot, content_type='image/png')