Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework RelatedField can't return a dict object

I have a serializer and I want to use a serializers.RelatedField so I can manipulate the content of one of the fields of the serializer. I want that field to nest a couple fields from a related table.

This is my serializer and the serializer.RelatedField. I want the 'city' field to return a nested object with the 'id' and the 'name' of the related city:

class CityRelatedField(serializers.RelatedField):
    def to_representation(self, value):
        city = {
            'id': value.id,
            'name': value.name
        }

        return city

class AirportSerializer(serializers.ModelSerializer):
    city = CityRelatedField(queryset=models.City.objects.all())

    class Meta:
        model = models.Airport
        fields = ('id', 'city', 'name', 'iata')

This is the error I get: TypeError: unhashable type: 'dict'

Thanks for your help.

like image 285
HuLu ViCa Avatar asked Oct 26 '25 18:10

HuLu ViCa


1 Answers

It seems that recent Django Rest Framework update has the default choice for a field retrieves from the result of the to_representation.

File location: venv/lib/python3.6/site-packages/rest_framework/relations.py Under RelatedField Class see get_choices method.

Opened issue

Possible solution: reference link

from collections import OrderedDict

class ModifiedRelatedField(serializers.RelatedField):
    def get_choices(self, cutoff=None):
        queryset = self.get_queryset()
        if queryset is None:
            # Ensure that field.choices returns something sensible
            # even when accessed with a read-only field.
        return {}

        if cutoff is not None:
            queryset = queryset[:cutoff]

        return OrderedDict([
            (
                item.pk,
                self.display_value(item)
            )
            for item in queryset
        ])

class CityRelatedField(ModifiedRelatedField):
    def to_representation(self, value):
        city = {
            'id': value.id,
            'name': value.name
        }

        return city

class AirportSerializer(serializers.ModelSerializer):
    city = CityRelatedField(queryset=models.City.objects.all())

    class Meta:
        model = models.Airport
        fields = ('id', 'city', 'name', 'iata')

Hope it will help.

like image 197
user1012513 Avatar answered Oct 29 '25 07:10

user1012513



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!