Skip to content

Commit

Permalink
Merge branch 'v0.4'
Browse files Browse the repository at this point in the history
  • Loading branch information
hmarr committed Oct 18, 2010
2 parents 34fa5cd + 2b9c526 commit 6998936
Show file tree
Hide file tree
Showing 23 changed files with 1,749 additions and 346 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
*.pyc
.*.swp
*.egg

This comment has been minimized.

Copy link
@handyjq

handyjq Mar 4, 2011

电风扇

docs/.build
docs/_build
build/
dist/
mongoengine.egg-info/
mongoengine.egg-info/
env/
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ Harry Marr <harry@hmarr.com>
Matt Dennewitz <mattdennewitz@gmail.com>
Deepak Thukral <iapain@yahoo.com>
Florian Schlachter <flori@n-schlachter.de>
Steve Challis <steve@stevechallis.com>
4 changes: 4 additions & 0 deletions docs/apireference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,7 @@ Fields
.. autoclass:: mongoengine.ReferenceField

.. autoclass:: mongoengine.GenericReferenceField

.. autoclass:: mongoengine.FileField

.. autoclass:: mongoengine.GeoPointField
26 changes: 26 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,32 @@
Changelog
=========

Changes in v0.4
===============
- Added ``GridFSStorage`` Django storage backend
- Added ``FileField`` for GridFS support
- New Q-object implementation, which is no longer based on Javascript
- Added ``SortedListField``
- Added ``EmailField``
- Added ``GeoPointField``
- Added ``exact`` and ``iexact`` match operators to ``QuerySet``
- Added ``get_document_or_404`` and ``get_list_or_404`` Django shortcuts
- Added new query operators for Geo queries
- Added ``not`` query operator
- Added new update operators: ``pop`` and ``add_to_set``
- Added ``__raw__`` query parameter
- Added support for custom querysets
- Fixed document inheritance primary key issue
- Added support for querying by array element position
- Base class can now be defined for ``DictField``
- Fixed MRO error that occured on document inheritance
- Added ``QuerySet.distinct``, ``QuerySet.create``, ``QuerySet.snapshot``,
``QuerySet.timeout`` and ``QuerySet.all``
- Subsequent calls to ``connect()`` now work
- Introduced ``min_length`` for ``StringField``
- Fixed multi-process connection issue
- Other minor fixes

Changes in v0.3
===============
- Added MapReduce support
Expand Down
43 changes: 42 additions & 1 deletion docs/django.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ MongoDB but still use many of the Django authentication infrastucture (such as
the :func:`login_required` decorator and the :func:`authenticate` function). To
enable the MongoEngine auth backend, add the following to you **settings.py**
file::

AUTHENTICATION_BACKENDS = (
'mongoengine.django.auth.MongoEngineBackend',
)
Expand All @@ -44,3 +44,44 @@ into you settings module::
SESSION_ENGINE = 'mongoengine.django.sessions'

.. versionadded:: 0.2.1

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

fs = mongoengine.django.GridFSStorage()

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

All of the `Django Storage API methods
<http://docs.djangoproject.com/en/dev/ref/files/storage/>`_ have been
implemented except :func:`path`. If the filename provided already exists, an
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
:func:`save` method will return the new filename.::

>>> fs.exists('hello.txt')
True
>>> fs.open('hello.txt').read()
'Hello, World!'
>>> fs.size('hello.txt')
13
>>> fs.url('hello.txt')
'http://your_media_url/hello.txt'
>>> fs.open('hello.txt').name
'hello.txt'
>>> fs.listdir()
([], [u'hello.txt'])

All files will be saved and retrieved in GridFS via the :class::`FileDocument`
document, allowing easy access to the files without the GridFSStorage
backend.::

>>> from mongoengine.django.storage import FileDocument
>>> FileDocument.objects()
[<FileDocument: FileDocument object>]

.. versionadded:: 0.4
43 changes: 43 additions & 0 deletions docs/guide/defining-documents.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ are as follows:
* :class:`~mongoengine.EmbeddedDocumentField`
* :class:`~mongoengine.ReferenceField`
* :class:`~mongoengine.GenericReferenceField`
* :class:`~mongoengine.BooleanField`
* :class:`~mongoengine.FileField`
* :class:`~mongoengine.EmailField`
* :class:`~mongoengine.SortedListField`
* :class:`~mongoengine.BinaryField`
* :class:`~mongoengine.GeoPointField`

Field arguments
---------------
Expand All @@ -66,6 +72,25 @@ arguments can be set on all fields:
:attr:`default` (Default: None)
A value to use when no value is set for this field.

The definion of default parameters follow `the general rules on Python
<http://docs.python.org/reference/compound_stmts.html#function-definitions>`__,
which means that some care should be taken when dealing with default mutable objects
(like in :class:`~mongoengine.ListField` or :class:`~mongoengine.DictField`)::

class ExampleFirst(Document):
# Default an empty list
values = ListField(IntField(), default=list)

class ExampleSecond(Document):
# Default a set of values
values = ListField(IntField(), default=lambda: [1,2,3])

class ExampleDangerous(Document):
# This can make an .append call to add values to the default (and all the following objects),
# instead to just an object
values = ListField(IntField(), default=[1,2,3])

:attr:`unique` (Default: False)
When True, no documents in the collection will have the same value for this
field.
Expand Down Expand Up @@ -214,6 +239,20 @@ either a single field name, or a list or tuple of field names::
first_name = StringField()
last_name = StringField(unique_with='first_name')

Skipping Document validation on save
------------------------------------
You can also skip the whole document validation process by setting
``validate=False`` when caling the :meth:`~mongoengine.document.Document.save`
method::

class Recipient(Document):
name = StringField()
email = EmailField()
recipient = Recipient(name='admin', email='root@localhost')
recipient.save() # will raise a ValidationError while
recipient.save(validate=False) # won't

Document collections
====================
Document classes that inherit **directly** from :class:`~mongoengine.Document`
Expand Down Expand Up @@ -259,6 +298,10 @@ or a **-** sign. Note that direction only matters on multi-field indexes. ::
meta = {
'indexes': ['title', ('title', '-rating')]
}

.. note::
Geospatial indexes will be automatically created for all
:class:`~mongoengine.GeoPointField`\ s

Ordering
========
Expand Down
7 changes: 7 additions & 0 deletions docs/guide/document-instances.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ you may still use :attr:`id` to access the primary key if you want::
>>> bob.id == bob.email == 'bob@example.com'
True

You can also access the document's "primary key" using the :attr:`pk` field; in
is an alias to :attr:`id`::

>>> page = Page(title="Another Test Page")
>>> page.save()
>>> page.id == page.pk

.. note::
If you define your own primary key field, the field implicitly becomes
required, so a :class:`ValidationError` will be thrown if you don't provide
Expand Down
83 changes: 83 additions & 0 deletions docs/guide/gridfs.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
======
GridFS
======

.. versionadded:: 0.4

Writing
-------

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
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 :class:`~mongoengine.FileField` is to use the
:func:`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()

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(genus='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')
1 change: 1 addition & 0 deletions docs/guide/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ User Guide
defining-documents
document-instances
querying
gridfs
Loading

0 comments on commit 6998936

Please sign in to comment.