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):
|
def to_internal_value(self, data):
|
||||||
return 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):
|
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.
|
# Tests for field input and output values.
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
|
|
||||||
|
@ -1045,7 +1074,6 @@ class TestListField(FieldValues):
|
||||||
]
|
]
|
||||||
field = serializers.ListField(child=serializers.IntegerField())
|
field = serializers.ListField(child=serializers.IntegerField())
|
||||||
|
|
||||||
|
|
||||||
# Tests for FieldField.
|
# Tests for FieldField.
|
||||||
# ---------------------
|
# ---------------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user