Added Binary support to UUID (MongoEngine/mongoengine#47)
This commit is contained in:
		| @@ -5,6 +5,7 @@ Changelog | |||||||
| Changes in 0.6.X | Changes in 0.6.X | ||||||
| ================ | ================ | ||||||
|  |  | ||||||
|  | - Added Binary support to UUID (MongoEngine/mongoengine#47) | ||||||
| - Fixed MapField lookup for fields without declared lookups (MongoEngine/mongoengine#46) | - Fixed MapField lookup for fields without declared lookups (MongoEngine/mongoengine#46) | ||||||
| - Fixed BinaryField python value issue (MongoEngine/mongoengine#48) | - Fixed BinaryField python value issue (MongoEngine/mongoengine#48) | ||||||
| - Fixed SequenceField non numeric value lookup (MongoEngine/mongoengine#41) | - Fixed SequenceField non numeric value lookup (MongoEngine/mongoengine#41) | ||||||
|   | |||||||
| @@ -4,9 +4,9 @@ import decimal | |||||||
| import gridfs | import gridfs | ||||||
| import re | import re | ||||||
| import uuid | import uuid | ||||||
|  | import warnings | ||||||
|  |  | ||||||
| from bson import Binary, DBRef, SON, ObjectId | from bson import Binary, DBRef, SON, ObjectId | ||||||
|  |  | ||||||
| from base import (BaseField, ComplexBaseField, ObjectIdField, | from base import (BaseField, ComplexBaseField, ObjectIdField, | ||||||
|                   ValidationError, get_document, BaseDocument) |                   ValidationError, get_document, BaseDocument) | ||||||
| from queryset import DO_NOTHING, QuerySet | from queryset import DO_NOTHING, QuerySet | ||||||
| @@ -1308,17 +1308,40 @@ class UUIDField(BaseField): | |||||||
|  |  | ||||||
|     .. versionadded:: 0.6 |     .. versionadded:: 0.6 | ||||||
|     """ |     """ | ||||||
|  |     _binary = None | ||||||
|  |  | ||||||
|     def __init__(self, **kwargs): |     def __init__(self, binary=None, **kwargs): | ||||||
|  |         """ | ||||||
|  |         Store UUID data in the database | ||||||
|  |  | ||||||
|  |         :param binary: (optional) boolean store as binary. | ||||||
|  |  | ||||||
|  |         .. versionchanged:: 0.6.19 | ||||||
|  |         """ | ||||||
|  |         if binary is None: | ||||||
|  |             binary = False | ||||||
|  |             msg = ("UUIDFields will soon default to store as binary, please " | ||||||
|  |                   "configure binary=False if you wish to store as a string") | ||||||
|  |             warnings.warn(msg, FutureWarning) | ||||||
|  |         self._binary = binary | ||||||
|         super(UUIDField, self).__init__(**kwargs) |         super(UUIDField, self).__init__(**kwargs) | ||||||
|  |  | ||||||
|     def to_python(self, value): |     def to_python(self, value): | ||||||
|  |         if not self.binary: | ||||||
|             if not isinstance(value, basestring): |             if not isinstance(value, basestring): | ||||||
|                 value = unicode(value) |                 value = unicode(value) | ||||||
|             return uuid.UUID(value) |             return uuid.UUID(value) | ||||||
|  |         return value | ||||||
|  |  | ||||||
|     def to_mongo(self, value): |     def to_mongo(self, value): | ||||||
|  |         if not self._binary: | ||||||
|             return unicode(value) |             return unicode(value) | ||||||
|  |         return value | ||||||
|  |  | ||||||
|  |     def prepare_query_value(self, op, value): | ||||||
|  |         if value is None: | ||||||
|  |             return None | ||||||
|  |         return self.to_mongo(value) | ||||||
|  |  | ||||||
|     def validate(self, value): |     def validate(self, value): | ||||||
|         if not isinstance(value, uuid.UUID): |         if not isinstance(value, uuid.UUID): | ||||||
|   | |||||||
| @@ -272,26 +272,55 @@ class FieldTest(unittest.TestCase): | |||||||
|         person.admin = 'Yes' |         person.admin = 'Yes' | ||||||
|         self.assertRaises(ValidationError, person.validate) |         self.assertRaises(ValidationError, person.validate) | ||||||
|  |  | ||||||
|     def test_uuid_validation(self): |     def test_uuid_field_string(self): | ||||||
|         """Ensure that invalid values cannot be assigned to UUID fields. |         """Test UUID fields storing as String | ||||||
|         """ |         """ | ||||||
|         class Person(Document): |         class Person(Document): | ||||||
|             api_key = UUIDField() |             api_key = UUIDField(binary=False) | ||||||
|  |  | ||||||
|  |         Person.drop_collection() | ||||||
|  |  | ||||||
|  |         uu = uuid.uuid4() | ||||||
|  |         Person(api_key=uu).save() | ||||||
|  |         self.assertEqual(1, Person.objects(api_key=uu).count()) | ||||||
|  |  | ||||||
|         person = Person() |         person = Person() | ||||||
|         # any uuid type is valid |         valid = (uuid.uuid4(), uuid.uuid1()) | ||||||
|         person.api_key = uuid.uuid4() |         for api_key in valid: | ||||||
|         person.validate() |             person.api_key = api_key | ||||||
|         person.api_key = uuid.uuid1() |  | ||||||
|             person.validate() |             person.validate() | ||||||
|  |  | ||||||
|         # last g cannot belong to an hex number |         invalid = ('9d159858-549b-4975-9f98-dd2f987c113g', | ||||||
|         person.api_key = '9d159858-549b-4975-9f98-dd2f987c113g' |                    '9d159858-549b-4975-9f98-dd2f987c113') | ||||||
|  |         for api_key in invalid: | ||||||
|  |             person.api_key = api_key | ||||||
|             self.assertRaises(ValidationError, person.validate) |             self.assertRaises(ValidationError, person.validate) | ||||||
|         # short strings don't validate |  | ||||||
|         person.api_key = '9d159858-549b-4975-9f98-dd2f987c113' |     def test_uuid_field_binary(self): | ||||||
|  |         """Test UUID fields storing as Binary object | ||||||
|  |         """ | ||||||
|  |         class Person(Document): | ||||||
|  |             api_key = UUIDField(binary=True) | ||||||
|  |  | ||||||
|  |         Person.drop_collection() | ||||||
|  |  | ||||||
|  |         uu = uuid.uuid4() | ||||||
|  |         Person(api_key=uu).save() | ||||||
|  |         self.assertEqual(1, Person.objects(api_key=uu).count()) | ||||||
|  |  | ||||||
|  |         person = Person() | ||||||
|  |         valid = (uuid.uuid4(), uuid.uuid1()) | ||||||
|  |         for api_key in valid: | ||||||
|  |             person.api_key = api_key | ||||||
|  |             person.validate() | ||||||
|  |  | ||||||
|  |         invalid = ('9d159858-549b-4975-9f98-dd2f987c113g', | ||||||
|  |                    '9d159858-549b-4975-9f98-dd2f987c113') | ||||||
|  |         for api_key in invalid: | ||||||
|  |             person.api_key = api_key | ||||||
|             self.assertRaises(ValidationError, person.validate) |             self.assertRaises(ValidationError, person.validate) | ||||||
|  |  | ||||||
|  |  | ||||||
|     def test_datetime_validation(self): |     def test_datetime_validation(self): | ||||||
|         """Ensure that invalid values cannot be assigned to datetime fields. |         """Ensure that invalid values cannot be assigned to datetime fields. | ||||||
|         """ |         """ | ||||||
| @@ -937,7 +966,7 @@ class FieldTest(unittest.TestCase): | |||||||
|             visited = MapField(DateTimeField()) |             visited = MapField(DateTimeField()) | ||||||
|  |  | ||||||
|         Log.drop_collection() |         Log.drop_collection() | ||||||
|         Log(name="wilson", visited={'friends': datetime.now()}).save() |         Log(name="wilson", visited={'friends': datetime.datetime.now()}).save() | ||||||
|  |  | ||||||
|         self.assertEqual(1, Log.objects( |         self.assertEqual(1, Log.objects( | ||||||
|                                 visited__friends__exists=True).count()) |                                 visited__friends__exists=True).count()) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user