mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-06 13:30:12 +03:00
recursive fields and a single test
This commit is contained in:
parent
7e921caf4b
commit
8fc9a7f267
|
@ -1196,6 +1196,38 @@ class HiddenField(Field):
|
|||
def to_internal_value(self, data):
|
||||
return data
|
||||
|
||||
class RecursiveField(Field):
|
||||
"""
|
||||
A field that gets its representation from its parent.
|
||||
|
||||
This method could be used to serialize a tree structure, a linked list, or
|
||||
even a directed acyclic graph. As with all recursive things, it is
|
||||
important to keep the base case in mind. In the case of the tree serializer
|
||||
example below, the base case is a node with an empty list of children. In
|
||||
the case of the list serializer below, the base case is when `next==None`.
|
||||
Above all, beware of cyclical references.
|
||||
|
||||
Examples:
|
||||
|
||||
class TreeSerializer(self):
|
||||
children = ListField(child=RecursiveField())
|
||||
|
||||
class ListSerializer(self):
|
||||
next = RecursiveField(allow_null=True)
|
||||
"""
|
||||
|
||||
def _get_parent(self):
|
||||
if hasattr(self.parent, 'child') and self.parent.child is self:
|
||||
# Recursive field nested inside of some kind of composite list field
|
||||
return self.parent.parent
|
||||
else:
|
||||
return self.parent
|
||||
|
||||
def to_representation(self, value):
|
||||
return self._get_parent().to_representation(value)
|
||||
|
||||
def to_internal_value(self, data):
|
||||
return self._get_parent().to_internal_value(data)
|
||||
|
||||
class SerializerMethodField(Field):
|
||||
"""
|
||||
|
|
|
@ -292,6 +292,35 @@ class TestCreateOnlyDefault:
|
|||
}
|
||||
|
||||
|
||||
# Tests for RecursiveField.
|
||||
# -------------------------
|
||||
class TestRecursiveField:
|
||||
def setup(self):
|
||||
class ListSerializer(serializers.Serializer):
|
||||
name = serializers.CharField()
|
||||
next = serializers.RecursiveField(allow_null=True)
|
||||
self.list_serializer = ListSerializer
|
||||
|
||||
class TreeSerializer(serializers.Serializer):
|
||||
name = serializers.CharField()
|
||||
children = serializers.ListField(child=serializers.RecursiveField())
|
||||
self.tree_serializer = TreeSerializer
|
||||
|
||||
def test_serialize_list(self):
|
||||
value = {
|
||||
'name':'first',
|
||||
'next': {
|
||||
'name':'second',
|
||||
'next':{
|
||||
'name':'third',
|
||||
'next':None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serializer = self.list_serializer(value)
|
||||
assert serializer.data == value
|
||||
|
||||
# Tests for field input and output values.
|
||||
# ----------------------------------------
|
||||
|
||||
|
@ -1045,7 +1074,6 @@ class TestListField(FieldValues):
|
|||
]
|
||||
field = serializers.ListField(child=serializers.IntegerField())
|
||||
|
||||
|
||||
# Tests for FieldField.
|
||||
# ---------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user