mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-30 18:09:59 +03:00
Introducing max_depth argument
This commit is contained in:
parent
82f936b7ec
commit
9c95d15cf2
|
@ -419,6 +419,12 @@ You could have the child objects nested recursively with the following serialize
|
||||||
model = TreeModel
|
model = TreeModel
|
||||||
exclude = ('id', )
|
exclude = ('id', )
|
||||||
|
|
||||||
|
By default, the number of recursions is made until no further objects are found (`max_depth=-1`).
|
||||||
|
|
||||||
|
However, you can restrict the number of recursions by passing the number of levels as `max_depth` argument:
|
||||||
|
|
||||||
|
children = RecursiveRelatedField(many=True, max_depth=1)
|
||||||
|
|
||||||
Note that as for now the the `RecursiveRelatedField` is read only.
|
Note that as for now the the `RecursiveRelatedField` is read only.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
@ -482,9 +482,10 @@ class HyperlinkedIdentityField(Field):
|
||||||
|
|
||||||
class RecursiveRelatedField(RelatedField):
|
class RecursiveRelatedField(RelatedField):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, max_depth=-1, *args, **kwargs):
|
||||||
super(RecursiveRelatedField, self).__init__(*args, **kwargs)
|
super(RecursiveRelatedField, self).__init__(*args, **kwargs)
|
||||||
# Forced read only.
|
# Forced read only.
|
||||||
|
self.max_depth = max_depth
|
||||||
self.read_only = True
|
self.read_only = True
|
||||||
|
|
||||||
def field_to_native(self, obj, field_name):
|
def field_to_native(self, obj, field_name):
|
||||||
|
@ -493,6 +494,12 @@ class RecursiveRelatedField(RelatedField):
|
||||||
serializer = serializer_class()
|
serializer = serializer_class()
|
||||||
serializer.initialize(self.parent, field_name)
|
serializer.initialize(self.parent, field_name)
|
||||||
|
|
||||||
|
if self.max_depth > -1:
|
||||||
|
if self.max_depth > 0:
|
||||||
|
serializer.fields[field_name].max_depth = self.max_depth - 1
|
||||||
|
else:
|
||||||
|
return [] if self.many else None
|
||||||
|
|
||||||
if self.many:
|
if self.many:
|
||||||
related_manager = getattr(obj, self.source or field_name)
|
related_manager = getattr(obj, self.source or field_name)
|
||||||
if not obj.__class__ == related_manager.model:
|
if not obj.__class__ == related_manager.model:
|
||||||
|
|
|
@ -23,6 +23,15 @@ class TreeSerializer(serializers.ModelSerializer):
|
||||||
exclude = ('id', )
|
exclude = ('id', )
|
||||||
|
|
||||||
|
|
||||||
|
class MaxDepthTreeSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
children = RecursiveRelatedField(many=True, max_depth=1)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = TreeModel
|
||||||
|
exclude = ('id', )
|
||||||
|
|
||||||
|
|
||||||
class ChainModel(models.Model):
|
class ChainModel(models.Model):
|
||||||
|
|
||||||
name = models.CharField(max_length=127)
|
name = models.CharField(max_length=127)
|
||||||
|
@ -115,3 +124,28 @@ class TestRecursiveRelatedField(TestCase):
|
||||||
}
|
}
|
||||||
self.assertEqual(serializer.data, expected)
|
self.assertEqual(serializer.data, expected)
|
||||||
|
|
||||||
|
def test_max_depth(self):
|
||||||
|
serializer = MaxDepthTreeSerializer(self.tree_root)
|
||||||
|
expected = {
|
||||||
|
'children': [
|
||||||
|
{
|
||||||
|
'children': [],
|
||||||
|
'name': 'Child 1:0',
|
||||||
|
'parent': 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'children': [],
|
||||||
|
'name': 'Child 1:1',
|
||||||
|
'parent': 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'children': [],
|
||||||
|
'name': 'Child 1:2',
|
||||||
|
'parent': 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'name': 'Tree Root',
|
||||||
|
'parent': None
|
||||||
|
}
|
||||||
|
self.assertEqual(serializer.data, expected)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user