Skip to content
This repository
Browse code

default natural key is a uuid

  • Loading branch information...
commit 95fa0bb767253c09c10e6d6cc2a53d355fc3981e 1 parent 3a1a266
Jason Kraus authored July 17, 2012
7  dockit/core/serializers/python.py
@@ -30,7 +30,7 @@ def end_object(self, obj):
30 30
         self.objects.append({
31 31
             "model"  : smart_unicode(obj._meta),
32 32
             "pk"     : smart_unicode(obj._get_pk_val(), strings_only=True),
33  
-            "natural_key": obj.natural_key(),
  33
+            "natural_key": obj.natural_key,
34 34
             "fields" : self._current,
35 35
         })
36 36
         self._current = None
@@ -49,8 +49,9 @@ def Deserializer(object_list, **options):
49 49
     for d in object_list:
50 50
         # Look up the model and starting build a dict of data for it.
51 51
         doc_cls = get_base_document(d["model"])
52  
-        data = {doc_cls._meta.pk.attname : doc_cls._meta.pk.to_python(d["pk"])}
53  
-        data.update(d['fields'])
  52
+        #data = {doc_cls._meta.pk.attname : doc_cls._meta.pk.to_python(d["pk"])}
  53
+        #data.update(d['fields'])
  54
+        data = d['fields']
54 55
         
55 56
         yield base.DeserializedObject(doc_cls.to_python(data), natural_key=d['natural_key'])
56 57
 
4  dockit/schema/fields.py
@@ -784,9 +784,7 @@ def to_portable_primitive(self, val):
784 784
             return val
785 785
         if val is None:
786 786
             return val
787  
-        if hasattr(val, 'natural_key'):
788  
-            return val.natural_key()
789  
-        return val.get_id()
  787
+        return val.natural_key
790 788
     
791 789
     def to_python(self, val, parent=None):
792 790
         if self.self_reference:
30  dockit/schema/schema.py
... ...
@@ -1,4 +1,5 @@
1 1
 import sys
  2
+import uuid
2 3
 
3 4
 from django.utils.encoding import force_unicode
4 5
 from django.utils.datastructures import SortedDict
@@ -133,7 +134,7 @@ def to_portable_primitive(cls, val):
133 134
         if cls._meta.typed_field and cls._meta.typed_key:
134 135
             val[cls._meta.typed_field] = cls._meta.typed_key
135 136
         if hasattr(val, '_primitive_data') and hasattr(val, '_python_data') and hasattr(val, '_meta'):
136  
-            data = {}
  137
+            data = dict(val._primitive_data)
137 138
             for name, entry in val._python_data.iteritems():
138 139
                 if name in val._meta.fields:
139 140
                     try:
@@ -339,28 +340,37 @@ def _get_pk_val(self):
339 340
     
340 341
     pk = property(get_id)
341 342
     
  343
+    def get_or_create_natural_key(self):
  344
+        if '@natural_key' not in self._primitive_data:
  345
+            self._primitive_data['@natural_key'] = self.create_natural_key()
  346
+            self._primitive_data['@natural_key_hash'] = self._get_natural_key_hash(self._primitive_data['@natural_key'])
  347
+        return self._primitive_data['@natural_key']
  348
+    
  349
+    def create_natural_key(self):
  350
+        '''
  351
+        Documents may want to override this to return a dictionary of values representing the natural key of the document.
  352
+        Other applications may want the natural key to be based off fields in the document rather then a UUID.
  353
+        '''
  354
+        return {'uuid': uuid.uuid4().hex}
  355
+    
  356
+    @property
342 357
     def natural_key(self):
343  
-        #documents should overide this
344  
-        #pk is a bad default, uuid may make more sense
345  
-        return {'pk':self.get_id()}
  358
+        return self.get_or_create_natural_key()
346 359
     
347  
-    def natural_key_hash(self):
348  
-        nkey = self.natural_key()
  360
+    def _get_natural_key_hash(self, nkey):
349 361
         vals = tuple(nkey.items())
350 362
         return hash(vals)
351 363
     
352 364
     @classmethod
353 365
     def to_primitive(cls, val):
  366
+        val.get_or_create_natural_key()
354 367
         ret = Schema.to_primitive(val)
355  
-        ret['@natural_key'] = val.natural_key()
356  
-        ret['@natural_key_hash'] = val.natural_key_hash()
357 368
         return ret
358 369
     
359 370
     @classmethod
360 371
     def to_portable_primitive(cls, val):
  372
+        val.get_or_create_natural_key()
361 373
         ret = Schema.to_portable_primitive(val)
362  
-        ret['@natural_key'] = val.natural_key()
363  
-        ret['@natural_key_hash'] = val.natural_key_hash()
364 374
         return ret
365 375
     
366 376
     def save(self):
10  dockit/tests/schema/schema.py
... ...
@@ -1,8 +1,6 @@
1  
-from dockit.schema.schema import create_document, create_schema
2  
-
3 1
 from django.utils import unittest
4 2
 
5  
-from common import SimpleSchema
  3
+from common import SimpleSchema, SimpleDocument
6 4
 
7 5
 class SchemaTestCase(unittest.TestCase):
8 6
     def test_to_primitive(self):
@@ -30,4 +28,10 @@ def test_from_portable_primitive(self):
30 28
     def test_traverse(self):
31 29
         obj = SimpleSchema(charfield='charmander')
32 30
         self.assertEqual(obj.dot_notation('charfield'), 'charmander')
  31
+    
  32
+    def test_natural_key_creation(self):
  33
+        obj = SimpleDocument()
  34
+        obj.save()
  35
+        self.assertTrue('@natural_key' in obj._primitive_data)
  36
+        self.assertTrue('@natural_key_hash' in obj._primitive_data)
33 37
 
11  dockit/tests/serializers/common.py
... ...
@@ -0,0 +1,11 @@
  1
+from dockit import schema
  2
+
  3
+class ChildDocument(schema.Document):
  4
+    charfield = schema.CharField()
  5
+    
  6
+    def create_natural_key(self):
  7
+        return {'charfield': self.charfield}
  8
+
  9
+class ParentDocument(schema.Document):
  10
+    title = schema.CharField()
  11
+    subdocument = schema.ReferenceField(ChildDocument)
7  dockit/tests/serializers/python.py
@@ -11,7 +11,10 @@ def setUp(self):
11 11
     def test_serialize(self):
12 12
         child = ChildDocument(charfield='bar')
13 13
         parent = ParentDocument(title='foo', subdocument=child)
  14
+        assert parent.natural_key
  15
+        assert '@natural_key' in parent._primitive_data
14 16
         data = parent.to_portable_primitive(parent)
  17
+        self.assertTrue('@natural_key' in data, str(data))
15 18
         result = self.serializer.serialize([child, parent])
16 19
         self.assertEqual(len(result), 2)
17 20
         entry = result[1]
@@ -20,8 +23,8 @@ def test_serialize(self):
20 23
         self.assertEqual(entry['fields'], data)
21 24
     
22 25
     def test_deserialize(self):
23  
-        payload = [{'natural_key': {'charfield': 'bar'}, 'pk': u'None', 'model': u'serializers.childdocument', 'fields': {'charfield': u'bar'}}, 
24  
-                   {'natural_key': {'pk': 'None'}, 'pk': u'None', 'model': u'serializers.parentdocument', 'fields': {'subdocument': {'charfield': 'bar'}, 'title': u'foo'}}]
  26
+        payload = [{'natural_key': {'charfield': 'bar'}, 'model': u'serializers.childdocument', 'fields': {'charfield': u'bar'}}, 
  27
+                   {'natural_key': {'uuid': 'DEADBEEF'}, 'model': u'serializers.parentdocument', 'fields': {'subdocument': {'charfield': 'bar'}, 'title': u'foo'}}]
25 28
         objects = list(Deserializer(payload))
26 29
         self.assertEqual(len(objects), 2)
27 30
         obj = objects[1]

0 notes on commit 95fa0bb

Please sign in to comment.
Something went wrong with that request. Please try again.