Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i filter queryset in nested serializer in django

I have this code

# Models

class NestedSample(models.Model):
    something = models.CharField(max_length=255)

class Sample(models.Model):
    thing = models.BooleanField()
    nested = models.ForeignKey(NestedSample)

# Serializers

class NestedSampleSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = api_models.NestedSample

class SampleSerializer(serializers.HyperlinkedModelSerializer):
    nested = NestedSampleSerializer() # HERE filter delete=false
    nested2 = NestedSample2Serializer() # HERE filter deletefalse

    class Meta:
        model = api_models.Sample

In my view I am overrding the queryset for delete=False but it is not applying to nested serializers.

like image 719
John Kaff Avatar asked Nov 22 '15 06:11

John Kaff


2 Answers

delete=False in queryset will only filter Sample. To filter queryset in nested serializer you can use serializers.ListSerializer like:

class FilterDeleteListSerializer(serializers.ListSerializer):
    def to_representation(self, data):
        data = data.filter(delete=False)
        return super(FilterDeleteListSerializer, self).to_representation(data)

class NestedSampleSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = api_models.NestedSample
        list_serializer_class = FilterDeleteListSerializer 

class NestedSample2Serializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = api_models.NestedSample2
        list_serializer_class = FilterDeleteListSerializer 

class SampleSerializer(serializers.HyperlinkedModelSerializer):
    nested = NestedSampleSerializer() # HERE filter delete=false
    nested2 = NestedSample2Serializer() # HERE filter deletefalse

    class Meta:
        model = api_models.Sample

Learn more here

like image 104
Anush Devendra Avatar answered Nov 13 '22 23:11

Anush Devendra


I didn't exactly understand your question, but from what I figured you've got a boolean field in your Model which is set to True if you delete the object instead of actually deleting it from the database (SQL DELETE).

Now coming to your question, if you just want to filter the nested serializer then you could use the SerializerMethodField. You need to specify the method to call as an argument or add a method with the name 'get_' followed by the field name. In this method you can filter the queryset serialize it and return the data of that queryset.

 class UserSerializer(serializers.ModelSerializer):
    delete_filtered_items = serializers.SerializerMethodField()

    class Meta:
        model = User

    def get_delete_filtered_items(self, obj):
        items = Item.objects.filter(user=obj,deleted=False)
        serializer = ItemsSerializer(instance=items, many=True)
        return serializer.data

The above solution should work for your requirements, but if what you've implemented is similar to a soft delete then it would seem cleaner and more moduler to create a custom model manager.

like image 24
Cliffton Fernandes Avatar answered Nov 13 '22 23:11

Cliffton Fernandes