Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

default natural key is a uuid

  • Loading branch information...
commit 95fa0bb767253c09c10e6d6cc2a53d355fc3981e 1 parent 3a1a266
Jason Kraus authored
7 dockit/core/serializers/python.py
View
@@ -30,7 +30,7 @@ def end_object(self, obj):
self.objects.append({
"model" : smart_unicode(obj._meta),
"pk" : smart_unicode(obj._get_pk_val(), strings_only=True),
- "natural_key": obj.natural_key(),
+ "natural_key": obj.natural_key,
"fields" : self._current,
})
self._current = None
@@ -49,8 +49,9 @@ def Deserializer(object_list, **options):
for d in object_list:
# Look up the model and starting build a dict of data for it.
doc_cls = get_base_document(d["model"])
- data = {doc_cls._meta.pk.attname : doc_cls._meta.pk.to_python(d["pk"])}
- data.update(d['fields'])
+ #data = {doc_cls._meta.pk.attname : doc_cls._meta.pk.to_python(d["pk"])}
+ #data.update(d['fields'])
+ data = d['fields']
yield base.DeserializedObject(doc_cls.to_python(data), natural_key=d['natural_key'])
4 dockit/schema/fields.py
View
@@ -784,9 +784,7 @@ def to_portable_primitive(self, val):
return val
if val is None:
return val
- if hasattr(val, 'natural_key'):
- return val.natural_key()
- return val.get_id()
+ return val.natural_key
def to_python(self, val, parent=None):
if self.self_reference:
30 dockit/schema/schema.py
View
@@ -1,4 +1,5 @@
import sys
+import uuid
from django.utils.encoding import force_unicode
from django.utils.datastructures import SortedDict
@@ -133,7 +134,7 @@ def to_portable_primitive(cls, val):
if cls._meta.typed_field and cls._meta.typed_key:
val[cls._meta.typed_field] = cls._meta.typed_key
if hasattr(val, '_primitive_data') and hasattr(val, '_python_data') and hasattr(val, '_meta'):
- data = {}
+ data = dict(val._primitive_data)
for name, entry in val._python_data.iteritems():
if name in val._meta.fields:
try:
@@ -339,28 +340,37 @@ def _get_pk_val(self):
pk = property(get_id)
+ def get_or_create_natural_key(self):
+ if '@natural_key' not in self._primitive_data:
+ self._primitive_data['@natural_key'] = self.create_natural_key()
+ self._primitive_data['@natural_key_hash'] = self._get_natural_key_hash(self._primitive_data['@natural_key'])
+ return self._primitive_data['@natural_key']
+
+ def create_natural_key(self):
+ '''
+ Documents may want to override this to return a dictionary of values representing the natural key of the document.
+ Other applications may want the natural key to be based off fields in the document rather then a UUID.
+ '''
+ return {'uuid': uuid.uuid4().hex}
+
+ @property
def natural_key(self):
- #documents should overide this
- #pk is a bad default, uuid may make more sense
- return {'pk':self.get_id()}
+ return self.get_or_create_natural_key()
- def natural_key_hash(self):
- nkey = self.natural_key()
+ def _get_natural_key_hash(self, nkey):
vals = tuple(nkey.items())
return hash(vals)
@classmethod
def to_primitive(cls, val):
+ val.get_or_create_natural_key()
ret = Schema.to_primitive(val)
- ret['@natural_key'] = val.natural_key()
- ret['@natural_key_hash'] = val.natural_key_hash()
return ret
@classmethod
def to_portable_primitive(cls, val):
+ val.get_or_create_natural_key()
ret = Schema.to_portable_primitive(val)
- ret['@natural_key'] = val.natural_key()
- ret['@natural_key_hash'] = val.natural_key_hash()
return ret
def save(self):
10 dockit/tests/schema/schema.py
View
@@ -1,8 +1,6 @@
-from dockit.schema.schema import create_document, create_schema
-
from django.utils import unittest
-from common import SimpleSchema
+from common import SimpleSchema, SimpleDocument
class SchemaTestCase(unittest.TestCase):
def test_to_primitive(self):
@@ -30,4 +28,10 @@ def test_from_portable_primitive(self):
def test_traverse(self):
obj = SimpleSchema(charfield='charmander')
self.assertEqual(obj.dot_notation('charfield'), 'charmander')
+
+ def test_natural_key_creation(self):
+ obj = SimpleDocument()
+ obj.save()
+ self.assertTrue('@natural_key' in obj._primitive_data)
+ self.assertTrue('@natural_key_hash' in obj._primitive_data)
11 dockit/tests/serializers/common.py
View
@@ -0,0 +1,11 @@
+from dockit import schema
+
+class ChildDocument(schema.Document):
+ charfield = schema.CharField()
+
+ def create_natural_key(self):
+ return {'charfield': self.charfield}
+
+class ParentDocument(schema.Document):
+ title = schema.CharField()
+ subdocument = schema.ReferenceField(ChildDocument)
7 dockit/tests/serializers/python.py
View
@@ -11,7 +11,10 @@ def setUp(self):
def test_serialize(self):
child = ChildDocument(charfield='bar')
parent = ParentDocument(title='foo', subdocument=child)
+ assert parent.natural_key
+ assert '@natural_key' in parent._primitive_data
data = parent.to_portable_primitive(parent)
+ self.assertTrue('@natural_key' in data, str(data))
result = self.serializer.serialize([child, parent])
self.assertEqual(len(result), 2)
entry = result[1]
@@ -20,8 +23,8 @@ def test_serialize(self):
self.assertEqual(entry['fields'], data)
def test_deserialize(self):
- payload = [{'natural_key': {'charfield': 'bar'}, 'pk': u'None', 'model': u'serializers.childdocument', 'fields': {'charfield': u'bar'}},
- {'natural_key': {'pk': 'None'}, 'pk': u'None', 'model': u'serializers.parentdocument', 'fields': {'subdocument': {'charfield': 'bar'}, 'title': u'foo'}}]
+ payload = [{'natural_key': {'charfield': 'bar'}, 'model': u'serializers.childdocument', 'fields': {'charfield': u'bar'}},
+ {'natural_key': {'uuid': 'DEADBEEF'}, 'model': u'serializers.parentdocument', 'fields': {'subdocument': {'charfield': 'bar'}, 'title': u'foo'}}]
objects = list(Deserializer(payload))
self.assertEqual(len(objects), 2)
obj = objects[1]
Please sign in to comment.
Something went wrong with that request. Please try again.