Skip to content

Commit

Permalink
Merge branch 'SortedListField' of git://github.com/joshourisman/mongo…
Browse files Browse the repository at this point in the history
…engine
  • Loading branch information
hmarr committed Apr 12, 2010
2 parents a39685d + c8e466a commit 2b08ca7
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
20 changes: 19 additions & 1 deletion mongoengine/fields.py
@@ -1,6 +1,7 @@
from base import BaseField, ObjectIdField, ValidationError, get_document
from document import Document, EmbeddedDocument
from connection import _get_db
from operator import itemgetter

import re
import pymongo
Expand All @@ -12,7 +13,7 @@
'DateTimeField', 'EmbeddedDocumentField', 'ListField', 'DictField',
'ObjectIdField', 'ReferenceField', 'ValidationError',
'DecimalField', 'URLField', 'GenericReferenceField',
'BinaryField']
'BinaryField', 'SortedListField']

RECURSIVE_REFERENCE_CONSTANT = 'self'

Expand Down Expand Up @@ -310,6 +311,23 @@ def prepare_query_value(self, op, value):
def lookup_member(self, member_name):
return self.field.lookup_member(member_name)

class SortedListField(ListField):
"""A ListField that sorts the contents of its list before writing to
the database in order to ensure that a sorted list is always
retrieved.
"""

_ordering = None

def __init__(self, field, **kwargs):
if 'ordering' in kwargs.keys():
self._ordering = kwargs.pop('ordering')
super(SortedListField, self).__init__(field, **kwargs)

def to_mongo(self, value):
if self._ordering is not None:
return sorted([self.field.to_mongo(item) for item in value], key=itemgetter(self._ordering))
return sorted([self.field.to_mongo(item) for item in value])

class DictField(BaseField):
"""A dictionary field that wraps a standard Python dictionary. This is
Expand Down
31 changes: 31 additions & 0 deletions tests/fields.py
Expand Up @@ -218,6 +218,37 @@ class BlogPost(Document):
post.comments = 'yay'
self.assertRaises(ValidationError, post.validate)

def test_sorted_list_sorting(self):
"""Ensure that a sorted list field properly sorts values.
"""
class Comment(EmbeddedDocument):
order = IntField()
content = StringField()

class BlogPost(Document):
content = StringField()
comments = SortedListField(EmbeddedDocumentField(Comment), ordering='order')
tags = SortedListField(StringField())

post = BlogPost(content='Went for a walk today...')
post.save()

post.tags = ['leisure', 'fun']
post.save()
post.reload()
self.assertEqual(post.tags, ['fun', 'leisure'])

comment1 = Comment(content='Good for you', order=1)
comment2 = Comment(content='Yay.', order=0)
comments = [comment1, comment2]
post.comments = comments
post.save()
post.reload()
self.assertEqual(post.comments[0].content, comment2.content)
self.assertEqual(post.comments[1].content, comment1.content)

BlogPost.drop_collection()

def test_dict_validation(self):
"""Ensure that dict types work as expected.
"""
Expand Down

0 comments on commit 2b08ca7

Please sign in to comment.