yezyilomo / django-restql

Turn your API made with Django REST Framework(DRF) into a GraphQL like API.
https://yezyilomo.github.io/django-restql
MIT License
616 stars 43 forks source link

Serializer to_representation() does not honor query #296

Open schajee opened 2 years ago

schajee commented 2 years ago

I have a model setup with a FILE object, and to_representation() to fetch additional file data.

class File(models.Model):
    name = models.CharField(max_length=100)
    file = models.FileField()

class FileSerializer(BaseSerializer):
    file = serializers.FileField()

    class Meta:
        model = File
        fields = '__all__'

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        file = {
            'url': str(instance.file.url), 
            'size': instance.file.size,
            'name': str(instance.file.name).split('.')[0],
            'type': str(instance.file.name).split('.')[-1]
        }
        representation['file'] = file
        return representation

If I try to only include name in the query query={name}, the result still includes file {name:...,file"...}. If I try to omit file using -file it ignores the query and returns all the fields {id:...,name:...,file"...}.

Any ideas?

yezyilomo commented 2 years ago

You’re adding fields after django-restql has run, so basically you’re adding fields after django-restql has excluded them. You could use SerializerMethodField to add other fields as

from rest_framework import serializers

class FileSerializer(serializers.ModelSerializer):
    url = serializers.SerializerMethodField()
    name = serializers.SerializerMethodField()
    size = serializers.SerializerMethodField()
    type = serializers.SerializerMethodField()

    class Meta:
        model = File
        fields = ['url', 'name', 'size', 'type']

    def get_url(self, instance):
      return str(instance.file.url)

    def get_size(self, instance):
      return instance.file.size

    def get_name(self, instance):
      return str(instance.file.name).split('.')[0]

    def get_type(self, instance):
      return str(instance.file.name).split('.')[-1]