Tim
Tim

Reputation: 1443

Exclude declared serializer fields in Django Rest Framework

In my project I just upgraded Django Rest Framework to version 3.6. Before, I was able to exclude a field that is declared on a serializer, now it prevents me from doing that.

class MyModelSerializer(Serializer):
    expensive_field = SerializerMethodField()

    class Meta:
        model = MyModel
        exclude = ['expensive_field']

    def get_expensive_field(self, obj):
        return expensive_calculation()

The reason why I want to do this is because there are a few method fields that are rather expensive to calculate and I only want to render them when requested explicitly.

The mechanism until now was to exclude those fields. When the fields parameter is set in a request a serializer is created on the fly that inherits from the regular serializer. It includes the previously excluded field.

Is there a way to achieve this with recent versions of DRF?

(Sure, I could create extra serializers for each such case. However, that's not generic, not something that is supported by DRF, and would also require an exponential number of serializers per view depending on the number of fields to exclude.)

Upvotes: 2

Views: 1707

Answers (1)

voll
voll

Reputation: 305

You could dynamically exclude the field on the serializer's constructor, like:

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    if not self.must_include_expensive_field():
        self.fields.pop('expensive_field')

def must_include_expensive_field(self):
    # Do your check here. You can use `self.context['request'].query_params`
    # but keep in mind it might not be set in some unusual cases thus use `try`

That way you won't have to create the subclass.

Upvotes: 3

Related Questions