Add value_decorator into SequenceField
Allows post processing of the calculated counter value.
This commit is contained in:
parent
1986e82783
commit
99fe1da345
@ -4,6 +4,7 @@ Changelog
|
|||||||
|
|
||||||
Changes in 0.8
|
Changes in 0.8
|
||||||
==============
|
==============
|
||||||
|
- Updated SequenceFields to allow post processing of the calculated counter value (MongoEngine/mongoengine#141)
|
||||||
- Added clean method to documents for pre validation data cleaning (MongoEngine/mongoengine#60)
|
- Added clean method to documents for pre validation data cleaning (MongoEngine/mongoengine#60)
|
||||||
- Added support setting for read prefrence at a query level (MongoEngine/mongoengine#157)
|
- Added support setting for read prefrence at a query level (MongoEngine/mongoengine#157)
|
||||||
- Added _instance to EmbeddedDocuments pointing to the parent (MongoEngine/mongoengine#139)
|
- Added _instance to EmbeddedDocuments pointing to the parent (MongoEngine/mongoengine#139)
|
||||||
|
@ -57,6 +57,13 @@ you will need to declare :attr:`allow_inheritance` in the meta data like so:
|
|||||||
meta = {'allow_inheritance': True}
|
meta = {'allow_inheritance': True}
|
||||||
|
|
||||||
|
|
||||||
|
SequenceFields
|
||||||
|
--------------
|
||||||
|
|
||||||
|
:class:`~mongoengine.fields.SequenceField`s now inherit from `BaseField` to
|
||||||
|
allow flexible storage of the calculated value. As such MIN and MAX settings
|
||||||
|
are no longer handled.
|
||||||
|
|
||||||
0.6 to 0.7
|
0.6 to 0.7
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
@ -1329,7 +1329,7 @@ class GeoPointField(BaseField):
|
|||||||
self.error('Both values in point must be float or int')
|
self.error('Both values in point must be float or int')
|
||||||
|
|
||||||
|
|
||||||
class SequenceField(IntField):
|
class SequenceField(BaseField):
|
||||||
"""Provides a sequental counter see:
|
"""Provides a sequental counter see:
|
||||||
http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-SequenceNumbers
|
http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-SequenceNumbers
|
||||||
|
|
||||||
@ -1341,15 +1341,26 @@ class SequenceField(IntField):
|
|||||||
cluster of machines, it is easier to create an object ID than have
|
cluster of machines, it is easier to create an object ID than have
|
||||||
global, uniformly increasing sequence numbers.
|
global, uniformly increasing sequence numbers.
|
||||||
|
|
||||||
|
Use any callable as `value_decorator` to transform calculated counter into
|
||||||
|
any value suitable for your needs, e.g. string or hexadecimal
|
||||||
|
representation of the default integer counter value.
|
||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
|
|
||||||
|
.. versionchanged:: 0.8 added `value_decorator`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_auto_gen = True
|
_auto_gen = True
|
||||||
|
COLLECTION_NAME = 'mongoengine.counters'
|
||||||
|
VALUE_DECORATOR = int
|
||||||
|
|
||||||
def __init__(self, collection_name=None, db_alias=None,
|
def __init__(self, collection_name=None, db_alias=None,
|
||||||
sequence_name=None, *args, **kwargs):
|
sequence_name=None, value_decorator=None, *args, **kwargs):
|
||||||
self.collection_name = collection_name or 'mongoengine.counters'
|
self.collection_name = collection_name or self.COLLECTION_NAME
|
||||||
self.db_alias = db_alias or DEFAULT_CONNECTION_NAME
|
self.db_alias = db_alias or DEFAULT_CONNECTION_NAME
|
||||||
self.sequence_name = sequence_name
|
self.sequence_name = sequence_name
|
||||||
|
self.value_decorator = (callable(value_decorator) and
|
||||||
|
value_decorator or self.VALUE_DECORATOR)
|
||||||
return super(SequenceField, self).__init__(*args, **kwargs)
|
return super(SequenceField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
@ -1364,24 +1375,16 @@ class SequenceField(IntField):
|
|||||||
update={"$inc": {"next": 1}},
|
update={"$inc": {"next": 1}},
|
||||||
new=True,
|
new=True,
|
||||||
upsert=True)
|
upsert=True)
|
||||||
return counter['next']
|
return self.value_decorator(counter['next'])
|
||||||
|
|
||||||
def __get__(self, instance, owner):
|
def __get__(self, instance, owner):
|
||||||
|
value = super(SequenceField, self).__get__(instance, owner)
|
||||||
if instance is None:
|
if value is None and instance._initialised:
|
||||||
return self
|
|
||||||
|
|
||||||
if not instance._data:
|
|
||||||
return
|
|
||||||
|
|
||||||
value = instance._data.get(self.name)
|
|
||||||
|
|
||||||
if not value and instance._initialised:
|
|
||||||
value = self.generate()
|
value = self.generate()
|
||||||
instance._data[self.name] = value
|
instance._data[self.name] = value
|
||||||
instance._mark_as_changed(self.name)
|
instance._mark_as_changed(self.name)
|
||||||
|
|
||||||
return int(value) if value else None
|
return value
|
||||||
|
|
||||||
def __set__(self, instance, value):
|
def __set__(self, instance, value):
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
import sys
|
||||||
|
sys.path[0:0] = [""]
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
@ -2184,6 +2187,27 @@ class FieldTest(unittest.TestCase):
|
|||||||
c = self.db['mongoengine.counters'].find_one({'_id': 'animal.id'})
|
c = self.db['mongoengine.counters'].find_one({'_id': 'animal.id'})
|
||||||
self.assertEqual(c['next'], 10)
|
self.assertEqual(c['next'], 10)
|
||||||
|
|
||||||
|
def test_sequence_field_value_decorator(self):
|
||||||
|
class Person(Document):
|
||||||
|
id = SequenceField(primary_key=True, value_decorator=str)
|
||||||
|
name = StringField()
|
||||||
|
|
||||||
|
self.db['mongoengine.counters'].drop()
|
||||||
|
Person.drop_collection()
|
||||||
|
|
||||||
|
for x in xrange(10):
|
||||||
|
p = Person(name="Person %s" % x)
|
||||||
|
p.save()
|
||||||
|
|
||||||
|
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
|
||||||
|
self.assertEqual(c['next'], 10)
|
||||||
|
|
||||||
|
ids = [i.id for i in Person.objects]
|
||||||
|
self.assertEqual(ids, map(str, range(1, 11)))
|
||||||
|
|
||||||
|
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
|
||||||
|
self.assertEqual(c['next'], 10)
|
||||||
|
|
||||||
def test_generic_embedded_document(self):
|
def test_generic_embedded_document(self):
|
||||||
class Car(EmbeddedDocument):
|
class Car(EmbeddedDocument):
|
||||||
name = StringField()
|
name = StringField()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user