Merge remote branch 'hmarr/master'
This commit is contained in:
commit
df5b1f3806
@ -46,6 +46,8 @@ Fields
|
|||||||
|
|
||||||
.. autoclass:: mongoengine.EmbeddedDocumentField
|
.. autoclass:: mongoengine.EmbeddedDocumentField
|
||||||
|
|
||||||
|
.. autoclass:: mongoengine.DictField
|
||||||
|
|
||||||
.. autoclass:: mongoengine.ListField
|
.. autoclass:: mongoengine.ListField
|
||||||
|
|
||||||
.. autoclass:: mongoengine.ObjectIdField
|
.. autoclass:: mongoengine.ObjectIdField
|
||||||
|
@ -39,6 +39,7 @@ are as follows:
|
|||||||
* :class:`~mongoengine.FloatField`
|
* :class:`~mongoengine.FloatField`
|
||||||
* :class:`~mongoengine.DateTimeField`
|
* :class:`~mongoengine.DateTimeField`
|
||||||
* :class:`~mongoengine.ListField`
|
* :class:`~mongoengine.ListField`
|
||||||
|
* :class:`~mongoengine.DictField`
|
||||||
* :class:`~mongoengine.ObjectIdField`
|
* :class:`~mongoengine.ObjectIdField`
|
||||||
* :class:`~mongoengine.EmbeddedDocumentField`
|
* :class:`~mongoengine.EmbeddedDocumentField`
|
||||||
* :class:`~mongoengine.ReferenceField`
|
* :class:`~mongoengine.ReferenceField`
|
||||||
@ -75,6 +76,23 @@ document class as the first argument::
|
|||||||
comment2 = Comment('Nice article!')
|
comment2 = Comment('Nice article!')
|
||||||
page = Page(comments=[comment1, comment2])
|
page = Page(comments=[comment1, comment2])
|
||||||
|
|
||||||
|
Dictionary Fields
|
||||||
|
-----------------
|
||||||
|
Often, an embedded document may be used instead of a dictionary -- generally
|
||||||
|
this is recommended as dictionaries don't support validation or custom field
|
||||||
|
types. However, sometimes you will not know the structure of what you want to
|
||||||
|
store; in this situation a :class:`~mongoengine.DictField` is appropriate::
|
||||||
|
|
||||||
|
class SurveyResponse(Document):
|
||||||
|
date = DateTimeField()
|
||||||
|
user = ReferenceField(User)
|
||||||
|
answers = DictField()
|
||||||
|
|
||||||
|
survey_response = SurveyResponse(date=datetime.now(), user=request.user)
|
||||||
|
response_form = ResponseForm(request.POST)
|
||||||
|
survey_response.answers = response_form.cleaned_data()
|
||||||
|
survey_response.save()
|
||||||
|
|
||||||
Reference fields
|
Reference fields
|
||||||
----------------
|
----------------
|
||||||
References may be stored to other documents in the database using the
|
References may be stored to other documents in the database using the
|
||||||
|
@ -8,7 +8,7 @@ import datetime
|
|||||||
|
|
||||||
|
|
||||||
__all__ = ['StringField', 'IntField', 'FloatField', 'BooleanField',
|
__all__ = ['StringField', 'IntField', 'FloatField', 'BooleanField',
|
||||||
'DateTimeField', 'EmbeddedDocumentField', 'ListField',
|
'DateTimeField', 'EmbeddedDocumentField', 'ListField', 'DictField',
|
||||||
'ObjectIdField', 'ReferenceField', 'ValidationError']
|
'ObjectIdField', 'ReferenceField', 'ValidationError']
|
||||||
|
|
||||||
|
|
||||||
@ -180,6 +180,28 @@ class ListField(BaseField):
|
|||||||
return self.field.lookup_member(member_name)
|
return self.field.lookup_member(member_name)
|
||||||
|
|
||||||
|
|
||||||
|
class DictField(BaseField):
|
||||||
|
"""A dictionary field that wraps a standard Python dictionary. This is
|
||||||
|
similar to an embedded document, but the structure is not defined.
|
||||||
|
|
||||||
|
.. versionadded:: 0.2.3
|
||||||
|
"""
|
||||||
|
|
||||||
|
def validate(self, value):
|
||||||
|
"""Make sure that a list of valid fields is being used.
|
||||||
|
"""
|
||||||
|
if not isinstance(value, dict):
|
||||||
|
raise ValidationError('Only dictionaries may be used in a '
|
||||||
|
'DictField')
|
||||||
|
|
||||||
|
if any(('.' in k or '$' in k) for k in value):
|
||||||
|
raise ValidationError('Invalid dictionary key name - keys may not '
|
||||||
|
'contain "." or "$" characters')
|
||||||
|
|
||||||
|
def lookup_member(self, member_name):
|
||||||
|
return BaseField(name=member_name)
|
||||||
|
|
||||||
|
|
||||||
class ReferenceField(BaseField):
|
class ReferenceField(BaseField):
|
||||||
"""A reference to a document that will be automatically dereferenced on
|
"""A reference to a document that will be automatically dereferenced on
|
||||||
access (lazily).
|
access (lazily).
|
||||||
|
@ -176,6 +176,28 @@ class FieldTest(unittest.TestCase):
|
|||||||
post.comments = 'yay'
|
post.comments = 'yay'
|
||||||
self.assertRaises(ValidationError, post.validate)
|
self.assertRaises(ValidationError, post.validate)
|
||||||
|
|
||||||
|
def test_dict_validation(self):
|
||||||
|
"""Ensure that dict types work as expected.
|
||||||
|
"""
|
||||||
|
class BlogPost(Document):
|
||||||
|
info = DictField()
|
||||||
|
|
||||||
|
post = BlogPost()
|
||||||
|
post.info = 'my post'
|
||||||
|
self.assertRaises(ValidationError, post.validate)
|
||||||
|
|
||||||
|
post.info = ['test', 'test']
|
||||||
|
self.assertRaises(ValidationError, post.validate)
|
||||||
|
|
||||||
|
post.info = {'$title': 'test'}
|
||||||
|
self.assertRaises(ValidationError, post.validate)
|
||||||
|
|
||||||
|
post.info = {'the.title': 'test'}
|
||||||
|
self.assertRaises(ValidationError, post.validate)
|
||||||
|
|
||||||
|
post.info = {'title': 'test'}
|
||||||
|
post.validate()
|
||||||
|
|
||||||
def test_embedded_document_validation(self):
|
def test_embedded_document_validation(self):
|
||||||
"""Ensure that invalid embedded documents cannot be assigned to
|
"""Ensure that invalid embedded documents cannot be assigned to
|
||||||
embedded document fields.
|
embedded document fields.
|
||||||
|
@ -277,6 +277,22 @@ class QuerySetTest(unittest.TestCase):
|
|||||||
|
|
||||||
BlogPost.drop_collection()
|
BlogPost.drop_collection()
|
||||||
|
|
||||||
|
def test_find_dict_item(self):
|
||||||
|
"""Ensure that DictField items may be found.
|
||||||
|
"""
|
||||||
|
class BlogPost(Document):
|
||||||
|
info = DictField()
|
||||||
|
|
||||||
|
BlogPost.drop_collection()
|
||||||
|
|
||||||
|
post = BlogPost(info={'title': 'test'})
|
||||||
|
post.save()
|
||||||
|
|
||||||
|
post_obj = BlogPost.objects(info__title='test').first()
|
||||||
|
self.assertEqual(post_obj.id, post.id)
|
||||||
|
|
||||||
|
BlogPost.drop_collection()
|
||||||
|
|
||||||
def test_q(self):
|
def test_q(self):
|
||||||
class BlogPost(Document):
|
class BlogPost(Document):
|
||||||
publish_date = DateTimeField()
|
publish_date = DateTimeField()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user