Skip to content

Commit 67736c8

Browse files
committed
Finished GridFS Documentation
* Also made GridFS replace test pass
1 parent 39e2773 commit 67736c8

File tree

4 files changed

+88
-28
lines changed

4 files changed

+88
-28
lines changed

docs/django.rst

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,39 +47,41 @@ into you settings module::
4747

4848
Storage
4949
=======
50-
With MongoEngine's support for GridFS via the FileField, it is useful to have a
51-
Django file storage backend that wraps this. The new storage module is called
52-
GridFSStorage. Using it is very similar to using the default FileSystemStorage.::
50+
With MongoEngine's support for GridFS via the :class:`~mongoengine.FileField`,
51+
it is useful to have a Django file storage backend that wraps this. The new
52+
storage module is called :class:`~mongoengine.django.GridFSStorage`. Using it
53+
is very similar to using the default FileSystemStorage.::
5354

5455
fs = mongoengine.django.GridFSStorage()
5556

5657
filename = fs.save('hello.txt', 'Hello, World!')
5758

5859
All of the `Django Storage API methods
5960
<http://docs.djangoproject.com/en/dev/ref/files/storage/>`_ have been
60-
implemented except ``path()``. If the filename provided already exists, an
61+
implemented except :func:`path`. If the filename provided already exists, an
6162
underscore and a number (before # the file extension, if one exists) will be
6263
appended to the filename until the generated filename doesn't exist. The
63-
``save()`` method will return the new filename.::
64+
:func:`save` method will return the new filename.::
6465

65-
> fs.exists('hello.txt')
66+
>>> fs.exists('hello.txt')
6667
True
67-
> fs.open('hello.txt').read()
68+
>>> fs.open('hello.txt').read()
6869
'Hello, World!'
69-
> fs.size('hello.txt')
70+
>>> fs.size('hello.txt')
7071
13
71-
> fs.url('hello.txt')
72+
>>> fs.url('hello.txt')
7273
'http://your_media_url/hello.txt'
73-
> fs.open('hello.txt').name
74+
>>> fs.open('hello.txt').name
7475
'hello.txt'
75-
> fs.listdir()
76+
>>> fs.listdir()
7677
([], [u'hello.txt'])
7778

78-
All files will be saved and retrieved in GridFS via the ``FileDocument`` document,
79-
allowing easy access to the files without the GridFSStorage backend.::
79+
All files will be saved and retrieved in GridFS via the :class::`FileDocument`
80+
document, allowing easy access to the files without the GridFSStorage
81+
backend.::
8082

81-
> from mongoengine.django.storage import FileDocument
82-
> FileDocument.objects()
83+
>>> from mongoengine.django.storage import FileDocument
84+
>>> FileDocument.objects()
8385
[<FileDocument: FileDocument object>]
8486

8587
.. versionadded:: 0.4

docs/guide/gridfs.rst

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
======
22
GridFS
33
======
4+
5+
.. versionadded:: 0.4
6+
7+
Writing
8+
-------
9+
410
GridFS support comes in the form of the :class:`~mongoengine.FileField` field
511
object. This field acts as a file-like object and provides a couple of
6-
different ways of inserting and retrieving data. Metadata such as content-type
7-
can also be stored alongside the stored files. In the following example, an
8-
document is created to store details about animals, including a photo:
12+
different ways of inserting and retrieving data. Arbitrary metadata such as
13+
content type can also be stored alongside the files. In the following example,
14+
a document is created to store details about animals, including a photo::
915

1016
class Animal(Document):
1117
genus = StringField()
@@ -14,13 +20,64 @@ document is created to store details about animals, including a photo:
1420

1521
marmot = Animal('Marmota', 'Sciuridae')
1622

17-
marmot_photo = open('marmot.jpg') # Retrieve a photo from disk
18-
marmot.photo = marmot_photo # Store the photo in the document
23+
marmot_photo = open('marmot.jpg', 'r') # Retrieve a photo from disk
24+
marmot.photo = marmot_photo # Store the photo in the document
25+
marmot.photo.content_type = 'image/jpeg' # Store metadata
1926

2027
marmot.save()
2128

22-
So adding file data to a document is as easy as adding data to any other
29+
Another way of writing to a :class:`~mongoengine.FileField` is to use the
30+
:func:`put` method. This allows for metadata to be stored in the same call as
31+
the file::
2332

24-
.. versionadded:: 0.4
33+
marmot.photo.put(marmot_photo, content_type='image/jpeg')
34+
35+
marmot.save()
36+
37+
Retrieval
38+
---------
39+
40+
So using the :class:`~mongoengine.FileField` is just like using any other
41+
field. The file can also be retrieved just as easily::
42+
43+
marmot = Animal.objects('Marmota').first()
44+
photo = marmot.photo.read()
45+
content_type = marmot.photo.content_type
46+
47+
Streaming
48+
---------
49+
50+
Streaming data into a :class:`~mongoengine.FileField` is achieved in a
51+
slightly different manner. First, a new file must be created by calling the
52+
:func:`new_file` method. Data can then be written using :func:`write`::
53+
54+
marmot.photo.new_file()
55+
marmot.photo.write('some_image_data')
56+
marmot.photo.write('some_more_image_data')
57+
marmot.photo.close()
58+
59+
marmot.photo.save()
60+
61+
Deletion
62+
--------
63+
64+
Deleting stored files is achieved with the :func:`delete` method::
65+
66+
marmot.photo.delete()
67+
68+
.. note::
69+
The FileField in a Document actually only stores the ID of a file in a
70+
separate GridFS collection. This means that deleting a document
71+
with a defined FileField does not actually delete the file. You must be
72+
careful to delete any files in a Document as above before deleting the
73+
Document itself.
74+
75+
76+
Replacing files
77+
---------------
2578

79+
Files can be replaced with the :func:`replace` method. This works just like
80+
the :func:`put` method so even metadata can (and should) be replaced::
2681

82+
another_marmot = open('another_marmot.png', 'r')
83+
marmot.photo.replace(another_marmot, content_type='image/png')

docs/guide/querying.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ arguments. The keys in the keyword arguments correspond to fields on the
3434
Fields on embedded documents may also be referred to using field lookup syntax
3535
by using a double-underscore in place of the dot in object attribute access
3636
syntax::
37-
37+
3838
# This will return a QuerySet that will only iterate over pages that have
3939
# been written by a user whose 'country' field is set to 'uk'
4040
uk_pages = Page.objects(author__country='uk')
@@ -67,7 +67,7 @@ Query operators
6767
===============
6868
Operators other than equality may also be used in queries; just attach the
6969
operator name to a key with a double-underscore::
70-
70+
7171
# Only find users whose age is 18 or less
7272
young_users = Users.objects(age__lte=18)
7373

@@ -144,7 +144,7 @@ You may also index the query to retrieve a single result. If an item at that
144144
index does not exists, an :class:`IndexError` will be raised. A shortcut for
145145
retrieving the first result and returning :attr:`None` if no result exists is
146146
provided (:meth:`~mongoengine.queryset.QuerySet.first`)::
147-
147+
148148
>>> # Make sure there are no users
149149
>>> User.drop_collection()
150150
>>> User.objects[0]
@@ -458,7 +458,7 @@ that you may use with these methods:
458458

459459
The syntax for atomic updates is similar to the querying syntax, but the
460460
modifier comes before the field, not after it::
461-
461+
462462
>>> post = BlogPost(title='Test', page_views=0, tags=['database'])
463463
>>> post.save()
464464
>>> BlogPost.objects(id=post.id).update_one(inc__page_views=1)

mongoengine/fields.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,14 +586,14 @@ def new_file(self, **kwargs):
586586

587587
def put(self, file, **kwargs):
588588
if self.grid_id:
589-
raise GridFSError('This document alreay has a file. Either delete '
589+
raise GridFSError('This document already has a file. Either delete '
590590
'it or call replace to overwrite it')
591591
self.grid_id = self.fs.put(file, **kwargs)
592592

593593
def write(self, string):
594594
if self.grid_id:
595595
if not self.newfile:
596-
raise GridFSError('This document alreay has a file. Either '
596+
raise GridFSError('This document already has a file. Either '
597597
'delete it or call replace to overwrite it')
598598
else:
599599
self.new_file()
@@ -622,6 +622,7 @@ def delete(self):
622622

623623
def replace(self, file, **kwargs):
624624
self.delete()
625+
self.grid_id = None
625626
self.put(file, **kwargs)
626627

627628
def close(self):

0 commit comments

Comments
 (0)