Last active
December 23, 2015 06:29
-
-
Save techiev2/6593878 to your computer and use it in GitHub Desktop.
BaseDocument definition for Mongoengine documents
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class BaseDocument(me.Document): | |
""" | |
Base document definition. | |
Defines the following attributes common to all derived models. | |
:attr created_at datetime: Creation time defaulting to UTC | |
:attr updated_at datetime: Updation time defaulting to UTC | |
Defines the following metadata for the derived models' support. | |
:attr allow_inheritance True: Required by Mongoengine. | |
Allows inheritance | |
:attr abstract True: Created derived class instances would use | |
a collection of <DerivedClass> | |
instead of BaseDocument.<DerivedClass> | |
""" | |
created_at = me.DateTimeField(default=dt.utcnow()) | |
updated_at = me.DateTimeField(default=dt.utcnow()) | |
deleted_at = me.DateTimeField() | |
meta = { | |
'indexes': [], | |
'sparse': True, | |
'allow_inheritance': True, | |
'date_str': '%d-%m-%Y' | |
} | |
def save(self, *args, **kwargs): | |
self.obj_id = self._get_collection().find({}).count() + 1 | |
super(BaseDocument, self).save(*args, **kwargs) | |
def update(self, *args, **kwargs): | |
super(BaseDocument, self).update(*args, **kwargs) | |
self.reload() | |
def json(self, fields=None, excludes=None, as_string=False): | |
# Pick up a list of fields for the JSON construct from the | |
# fields param. If fields is not list/tuple, initialize an | |
# empty list and get export fields from inherited model meta. | |
# If neither is True, fetch a list of all keys from _fields | |
# attribute for instance. | |
# Inherited model meta declaration to get metadata for operation | |
obj_meta = getattr(self, '_meta', {}) | |
fields = [] if not isinstance(fields, (list, tuple)) else fields | |
fields.extend(obj_meta.get('export_fields', [])) | |
fields = fields or getattr(self, '_fields').iterkeys() | |
# Pick up a list of fields for the JSON construct from the | |
# excludes param. If fields is not list/tuple, initialize an | |
# empty list and get exclude fields from inherited model meta. | |
excludes = [] if not isinstance( | |
excludes, (list, tuple)) else excludes | |
excludes = excludes or obj_meta.get('exclude_fields', []) or [] | |
# Dumper considerations | |
# If it is a reference field, and thus has a to_mongo attr | |
# do a reload before attempting a json dump of the object | |
# instance. Alternatively, could consider | |
# QueryObject('<Model>', {'pk':<pk>}) to update. | |
# A Spec test should decide the better alternative. | |
ret_val = {x: getattr(self, x).reload().json() if hasattr( | |
getattr(self, x), 'to_mongo') else [ | |
y.reload().json() if hasattr(y, 'to_mongo') else unicode(y) for y | |
in getattr(self, x)] if isinstance( | |
getattr(self, x), me.base.datastructures.BaseList) | |
else getattr(self, x) if isinstance(getattr(self, x), | |
me.base.datastructures.BaseDict) else unicode( | |
dt.strftime(getattr(self, x), obj_meta.get('date_str', | |
'%d-%m-%Y'))) if isinstance(getattr(self, x), dt) else \ | |
unicode(getattr(self, x)) if getattr(self, x) else None \ | |
for x in fields if hasattr(self, x) and not x in excludes} | |
return ret_val if not as_string else json.dumps(ret_val) | |
class UserDocument(BaseDocument): | |
"""User document definition""" | |
username = me.StringField(unique=True) | |
email = me.EmailField(required=True, | |
unique=True) | |
metadata = me.DictField() | |
meta = { | |
'indexes': ['username'], | |
'export_fields': ['username', 'email'], | |
'exclude_fields': ['_id'] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment