简体   繁体   中英

Django Rest Framework - How to serialize nested fields

I have a CustomerSerializer which uses a reverse foreign key field images to return all associated Image objects.

class CustomerSerializer(serializers.ModelSerializer):

    class Meta:
        model = Customer
        fields = ('id', 'name', 'images')
        read_only_fields = ('id',)

class ImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Image
        fields = ('id', 'name', 'customer')
        read_only_fields = ('id',)

This is what I get from the response:

[
   {
       'id': 1,
       'name': 'John Doe',
       'images': [
               1,
               2,
               3,
               4,
               ...
       ]
   }
   ...
]

Question: Instead of just showing images as a list of id s, how can I show a different property ie name ?

The desired result would be:

[
   {
       'id': 1,
       'name': 'John Doe',
       'images': [
               'foo.jpg',
               'bar.jpg',
               'foobar.jpg',
               'lorem.jpg',
               ...
       ]
   }
   ...
]

My first attempt - I replaced the reverse foreign key images with image_names from the SerializerMethodField() in order to select the field name , but I get a null value.

class CustomerSerializer(serializers.ModelSerializer):
    image_names = serializers.SerializerMethodField()

    def get_image_names(self, obj):
        return obj.images.name

    class Meta:
        model = Customer
        fields = ('id', 'name', 'image_names')
        read_only_fields = ('id',)

Additional Info

Example models:

class Customer(models.Model):
      name = models.CharField()

class Image(models.Model):
      name = models.CharField()
      customer = models.ForeignKey(
        Customer, related_name='images', on_delete=models.CASCADE)

Please let me know if anything is unclear and I will update the question. Thank you.

You need to make another serializer like below

class ImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Image
        fields = ('name',)

then update your Customerserializer as below

class CustomerSerializer(serializers.ModelSerializer):
    images = ImageSerializer(many=True, read_only=True)
    class Meta:
        model = Customer
        fields = ('id', 'name', 'images')

Method 2:

class CustomerSerializer(serializers.ModelSerializer):
    images = serializers.SerializerMethodField()
    class Meta:
        model = Customer
        fields = ('id', 'name', 'images')
    def get_images(self, obj):
        image_names = obj.images.all().values_list('name', flat=True)
        return image_names

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM