Finished GridFS Documentation
* Also made GridFS replace test pass
This commit is contained in:
parent
39e27735cc
commit
67736c849d
@ -47,9 +47,10 @@ into you settings module::
|
|||||||
|
|
||||||
Storage
|
Storage
|
||||||
=======
|
=======
|
||||||
With MongoEngine's support for GridFS via the FileField, it is useful to have a
|
With MongoEngine's support for GridFS via the :class:`~mongoengine.FileField`,
|
||||||
Django file storage backend that wraps this. The new storage module is called
|
it is useful to have a Django file storage backend that wraps this. The new
|
||||||
GridFSStorage. Using it is very similar to using the default FileSystemStorage.::
|
storage module is called :class:`~mongoengine.django.GridFSStorage`. Using it
|
||||||
|
is very similar to using the default FileSystemStorage.::
|
||||||
|
|
||||||
fs = mongoengine.django.GridFSStorage()
|
fs = mongoengine.django.GridFSStorage()
|
||||||
|
|
||||||
@ -57,29 +58,30 @@ GridFSStorage. Using it is very similar to using the default FileSystemStorage.:
|
|||||||
|
|
||||||
All of the `Django Storage API methods
|
All of the `Django Storage API methods
|
||||||
<http://docs.djangoproject.com/en/dev/ref/files/storage/>`_ have been
|
<http://docs.djangoproject.com/en/dev/ref/files/storage/>`_ have been
|
||||||
implemented except ``path()``. If the filename provided already exists, an
|
implemented except :func:`path`. If the filename provided already exists, an
|
||||||
underscore and a number (before # the file extension, if one exists) will be
|
underscore and a number (before # the file extension, if one exists) will be
|
||||||
appended to the filename until the generated filename doesn't exist. The
|
appended to the filename until the generated filename doesn't exist. The
|
||||||
``save()`` method will return the new filename.::
|
:func:`save` method will return the new filename.::
|
||||||
|
|
||||||
> fs.exists('hello.txt')
|
>>> fs.exists('hello.txt')
|
||||||
True
|
True
|
||||||
> fs.open('hello.txt').read()
|
>>> fs.open('hello.txt').read()
|
||||||
'Hello, World!'
|
'Hello, World!'
|
||||||
> fs.size('hello.txt')
|
>>> fs.size('hello.txt')
|
||||||
13
|
13
|
||||||
> fs.url('hello.txt')
|
>>> fs.url('hello.txt')
|
||||||
'http://your_media_url/hello.txt'
|
'http://your_media_url/hello.txt'
|
||||||
> fs.open('hello.txt').name
|
>>> fs.open('hello.txt').name
|
||||||
'hello.txt'
|
'hello.txt'
|
||||||
> fs.listdir()
|
>>> fs.listdir()
|
||||||
([], [u'hello.txt'])
|
([], [u'hello.txt'])
|
||||||
|
|
||||||
All files will be saved and retrieved in GridFS via the ``FileDocument`` document,
|
All files will be saved and retrieved in GridFS via the :class::`FileDocument`
|
||||||
allowing easy access to the files without the GridFSStorage backend.::
|
document, allowing easy access to the files without the GridFSStorage
|
||||||
|
backend.::
|
||||||
|
|
||||||
> from mongoengine.django.storage import FileDocument
|
>>> from mongoengine.django.storage import FileDocument
|
||||||
> FileDocument.objects()
|
>>> FileDocument.objects()
|
||||||
[<FileDocument: FileDocument object>]
|
[<FileDocument: FileDocument object>]
|
||||||
|
|
||||||
.. versionadded:: 0.4
|
.. versionadded:: 0.4
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
======
|
======
|
||||||
GridFS
|
GridFS
|
||||||
======
|
======
|
||||||
|
|
||||||
|
.. versionadded:: 0.4
|
||||||
|
|
||||||
|
Writing
|
||||||
|
-------
|
||||||
|
|
||||||
GridFS support comes in the form of the :class:`~mongoengine.FileField` field
|
GridFS support comes in the form of the :class:`~mongoengine.FileField` field
|
||||||
object. This field acts as a file-like object and provides a couple of
|
object. This field acts as a file-like object and provides a couple of
|
||||||
different ways of inserting and retrieving data. Metadata such as content-type
|
different ways of inserting and retrieving data. Arbitrary metadata such as
|
||||||
can also be stored alongside the stored files. In the following example, an
|
content type can also be stored alongside the files. In the following example,
|
||||||
document is created to store details about animals, including a photo:
|
a document is created to store details about animals, including a photo::
|
||||||
|
|
||||||
class Animal(Document):
|
class Animal(Document):
|
||||||
genus = StringField()
|
genus = StringField()
|
||||||
@ -14,13 +20,64 @@ document is created to store details about animals, including a photo:
|
|||||||
|
|
||||||
marmot = Animal('Marmota', 'Sciuridae')
|
marmot = Animal('Marmota', 'Sciuridae')
|
||||||
|
|
||||||
marmot_photo = open('marmot.jpg') # Retrieve a photo from disk
|
marmot_photo = open('marmot.jpg', 'r') # Retrieve a photo from disk
|
||||||
marmot.photo = marmot_photo # Store the photo in the document
|
marmot.photo = marmot_photo # Store the photo in the document
|
||||||
|
marmot.photo.content_type = 'image/jpeg' # Store metadata
|
||||||
|
|
||||||
marmot.save()
|
marmot.save()
|
||||||
|
|
||||||
So adding file data to a document is as easy as adding data to any other
|
Another way of writing to a :class:`~mongoengine.FileField` is to use the
|
||||||
|
:func:`put` method. This allows for metadata to be stored in the same call as
|
||||||
|
the file::
|
||||||
|
|
||||||
.. versionadded:: 0.4
|
marmot.photo.put(marmot_photo, content_type='image/jpeg')
|
||||||
|
|
||||||
|
marmot.save()
|
||||||
|
|
||||||
|
Retrieval
|
||||||
|
---------
|
||||||
|
|
||||||
|
So using the :class:`~mongoengine.FileField` is just like using any other
|
||||||
|
field. The file can also be retrieved just as easily::
|
||||||
|
|
||||||
|
marmot = Animal.objects('Marmota').first()
|
||||||
|
photo = marmot.photo.read()
|
||||||
|
content_type = marmot.photo.content_type
|
||||||
|
|
||||||
|
Streaming
|
||||||
|
---------
|
||||||
|
|
||||||
|
Streaming data into a :class:`~mongoengine.FileField` is achieved in a
|
||||||
|
slightly different manner. First, a new file must be created by calling the
|
||||||
|
:func:`new_file` method. Data can then be written using :func:`write`::
|
||||||
|
|
||||||
|
marmot.photo.new_file()
|
||||||
|
marmot.photo.write('some_image_data')
|
||||||
|
marmot.photo.write('some_more_image_data')
|
||||||
|
marmot.photo.close()
|
||||||
|
|
||||||
|
marmot.photo.save()
|
||||||
|
|
||||||
|
Deletion
|
||||||
|
--------
|
||||||
|
|
||||||
|
Deleting stored files is achieved with the :func:`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 deleting a document
|
||||||
|
with a defined FileField does not actually delete the file. You must be
|
||||||
|
careful to delete any files in a Document as above before deleting the
|
||||||
|
Document itself.
|
||||||
|
|
||||||
|
|
||||||
|
Replacing files
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Files can be replaced with the :func:`replace` method. This works just like
|
||||||
|
the :func:`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')
|
||||||
|
@ -586,14 +586,14 @@ class GridFSProxy(object):
|
|||||||
|
|
||||||
def put(self, file, **kwargs):
|
def put(self, file, **kwargs):
|
||||||
if self.grid_id:
|
if self.grid_id:
|
||||||
raise GridFSError('This document alreay has a file. Either delete '
|
raise GridFSError('This document already has a file. Either delete '
|
||||||
'it or call replace to overwrite it')
|
'it or call replace to overwrite it')
|
||||||
self.grid_id = self.fs.put(file, **kwargs)
|
self.grid_id = self.fs.put(file, **kwargs)
|
||||||
|
|
||||||
def write(self, string):
|
def write(self, string):
|
||||||
if self.grid_id:
|
if self.grid_id:
|
||||||
if not self.newfile:
|
if not self.newfile:
|
||||||
raise GridFSError('This document alreay has a file. Either '
|
raise GridFSError('This document already has a file. Either '
|
||||||
'delete it or call replace to overwrite it')
|
'delete it or call replace to overwrite it')
|
||||||
else:
|
else:
|
||||||
self.new_file()
|
self.new_file()
|
||||||
@ -622,6 +622,7 @@ class GridFSProxy(object):
|
|||||||
|
|
||||||
def replace(self, file, **kwargs):
|
def replace(self, file, **kwargs):
|
||||||
self.delete()
|
self.delete()
|
||||||
|
self.grid_id = None
|
||||||
self.put(file, **kwargs)
|
self.put(file, **kwargs)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user