Django DRF嵌套序列化器未链接

时间:2020-05-14 20:38:27

标签: python django django-rest-framework

我正在尝试使用Django和Django Rest Framework for the API为图片库构建API。

我已经建立了以下两个模型:

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)

对于序列化程序,我已经使用官方的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__'

现在,我已经定义了一些对象,所以我想在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)

您会注意到序列化数据中没有pictures,但是当我打印序列化程序时该字段在那里,这就是我的问题...我错过了什么东西吗?

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您的问题是由于为ForeignKeys提供了related name

现在使用您提供的代码,名称反向关系名称应为picture_set。因此,要使序列化程序正常工作,您应该进行以下更改:

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

    class Meta:
        model = Album
        fields = '__all__'

但是,如果您想显示为pictures,还可以执行以下操作:

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

    class Meta:
        model = Album
        fields = '__all__'

最后,如果您想摆脱picture_set,则应将代码更改为以下内容:

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__'