@@ -1687,7 +1687,23 @@ def _validate(self, value):
16871687 """
16881688 methods = self ._find_methods ("_validate" , "_to_base_type" )
16891689 call = self ._apply_list (methods )
1690- return call (value )
1690+ value = call (value )
1691+
1692+ # Legacy NDB, because it didn't delegate to Datastore for serializing
1693+ # entities, would directly write a Key protocol buffer for a key. We,
1694+ # however, need to transform NDB keys to Datastore keys before
1695+ # delegating to Datastore to generate protocol buffers. You might be
1696+ # tempted to do this in KeyProperty._to_base_type, and that works great
1697+ # for properties of KeyProperty type. If, however, you're computing a
1698+ # key in a ComputedProperty, ComputedProperty doesn't know to call
1699+ # KeyProperty's base type. (Probably ComputedProperty should take
1700+ # another property type as a constructor argument for this purpose,
1701+ # but that wasn't part of the original design and adding it introduces
1702+ # backwards compatibility issues.) See: Issue #184
1703+ if isinstance (value , key_module .Key ):
1704+ value = value ._key # Datastore key
1705+
1706+ return value
16911707
16921708 def _call_shallow_validation (self , value ):
16931709 """Call the "initial" set of ``_validate()`` methods.
0 commit comments