Using Python 3.x and the Django Rest Framework. I have a serializer with a Recursive Field
(on self) which works as expected. However, I need a way to initially filter the nested children it returns by active = True
.
I've tried different ways to filter children by active=True, but I'm unable to get this working on the nested children that are returned in the serializer.
Here is what I have.
class MenuListSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='menu_detail')
children = RecursiveField(many=True, required=False)
class RecursiveField(serializers.Serializer):
"""
Self-referential field for MPTT.
"""
def to_representation(self, value):
serializer = self.parent.parent.__class__(value, context=self.context)
return serializer.data
This is what I have tried but get the error ListSerializer' object has no attribute 'queryset' However, I'm not even sure this would work.
class MenuListSerializer(serializers.ModelSerializer):
def __init__(self, *args, request_user=None, **kwargs):
# try and filter active in chrildrend before query set is passed
super(MenuListSerializer, self).__init__(*args, **kwargs)
# print(self.fields['children'].parent)
self.fields['children'].queryset = self.fields['children'].queryset.filter(active=True)
url = serializers.HyperlinkedIdentityField(view_name='menu_detail')
children = RecursiveField(many=True, required=False)
If I understand well, your are trying to serialize Menu
objects in a hierarchical way.
To do that, I guess you serialize recursively your top level Menu objects, don't you? (or else you will get all Menu objects at the top level).
To be able to filter active children only, I would suggest to create a active_children
property on your model:
class Menu(MPTTModel, TimeStampedModel):
name = models.CharField(max_length=100)
active = models.BooleanField(default=1)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
@property
def active_children(self):
return self.children.filter(active=True)
Then you can use that as a source for your children
field in you serializer:
class MenuListSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='menu_detail')
children = RecursiveField(many=True, required=False, source='active_children')
Now you should only have active children when serializing.
Note that you should also filter top level objects in your queryset as the filtering above only works for the children in Menu
objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With