简体   繁体   中英

Django DRF nested serializers are not linked

I'm trying to build an API for a picture gallery using Django and Django Rest Framework for the API.

I have set up the following two models:

class Album(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField(null=True, blank=True)
    start_date = models.DateField()
    end_date = models.DateField(null=True, blank=True)
    parent_album = models.ForeignKey('self',
                                     null=True,
                                     blank=True,
                                     on_delete=models.CASCADE
                                    )

class Picture(models.Model):
    path = models.ImageField()
    album = models.ForeignKey('Album', on_delete=models.CASCADE)

For the serializers, I have defined the following, using the official Django DRF doc :

class PictureSerializer(serializers.ModelSerializer):

    class Meta:
        model = Picture
        fields = '__all__'


class AlbumSerializer(serializers.ModelSerializer):
    pictures = PictureSerializer(many=True, read_only=True)

    class Meta:
        model = Album
        fields = '__all__'

Now, I have some objects already defined, so I wanted to try in a shell:

>>> album = Album.objects.get(pk=1)
>>> len(Picture.objects.filter(album__exact=Album.objects.get(pk=1)))
3
>>> AlbumSerializer(instance=album).data
{'id': 1, 'name': 'First album', 'description': '', 'start_date': '2019-08-15', 'end_date': None, 'parent_album': None}
>>> AlbumSerializer()
AlbumSerializer():
    id = IntegerField(label='ID', read_only=True)
    pictures = PictureSerializer(many=True, read_only=True):
        id = IntegerField(label='ID', read_only=True)
        path = ImageField(max_length=100)
        album = PrimaryKeyRelatedField(queryset=Album.objects.all())
    name = CharField(max_length=100)
    description = CharField(allow_blank=True, allow_null=True, required=False, style={'base_template': 'textarea.html'})
    start_date = DateField()
    end_date = DateField(allow_null=True, required=False)
    parent_album = PrimaryKeyRelatedField(allow_null=True, queryset=Album.objects.all(), required=False)

You will notice that there are no pictures in the serialized data, but the field is there when I print the serializer, and that's my problem... Have I missed something somewhere?

Thanks for the help!

Your problem is due to the related name given to ForeignKeys.

Right now with the code you provided the name backwards relation name should be picture_set . So for the serializer to work you should change it do the following:

class AlbumSerializer(serializers.ModelSerializer):
    picture_set = PictureSerializer(many=True, read_only=True)

    class Meta:
        model = Album
        fields = '__all__'

But, if you want to display as pictures you can also do the following:

class AlbumSerializer(serializers.ModelSerializer):
    pictures = PictureSerializer(many=True, read_only=True, source='picture_set')

    class Meta:
        model = Album
        fields = '__all__'

Finally, if you want to get rid of the picture_set you should change your code to the following:

models.py

class Picture(models.Model):
    path = models.ImageField()
    album = models.ForeignKey('Album', on_delete=models.CASCADE, related_name='pictures')

serializers.py

class AlbumSerializer(serializers.ModelSerializer):
    pictures = PictureSerializer(many=True, read_only=True)

    class Meta:
        model = Album
        fields = '__all__'

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