Django Rest Framework在API中显示多对多关系

时间:2018-05-31 18:10:49

标签: django-rest-framework

我的小播客后端有一些模型,其中一个是剧集。现在有两个新的客人(访客)和主题(主题) - 两者都有一个ManyToManyField到Episode。这基本上可以在管理员中使用。现在我需要将它带到API。

每集的详细Serializer / View已经有一些其他相关数据(到目前为止没有多对多)。我还检查了this post,但仍然无法让它发挥作用,并认为我可能会错过一些东西。

这就是客户示例保持密集的本质,主题完全相同:

剧集模特:

class Episode(models.Model):
    number          = models.CharField(max_length=10, blank=False)
    title           = models.CharField(max_length=100, blank=False)
    show            = models.ForeignKey(Show, on_delete=models.PROTECT)
    created_at      = models.DateTimeField(auto_now=False)
    published_at    = models.DateTimeField(auto_now=False)
    updated_at      = models.DateTimeField(auto_now=False)
    cover_image     = models.URLField(null=True)

    def __str__(self):
        return self.title

嘉宾模特:

class Guest(models.Model):
    episodes        = models.ManyToManyField(Episode)
    name            = models.CharField(max_length=100, blank=False)
    twitter         = models.CharField(max_length=20, null=True)

    def __str__(self):
        return self.name

串行:

class GuestSerializer(serializers.ModelSerializer):
    class Meta:
        model = Guest
        fields = ('name',)

Episode Serializer应该出现在哪里:

class EpisodeDetailSerializer(serializers.ModelSerializer):
    ...
    guest = GuestSerializer(many=True, read_only=True)
    topic = TopicSerializer(many=True, read_only=True)

    class Meta:
        model = Episode
        fields = (..., 'guest', 'topic')
        depth = 1

我已经为访客和主题提供了一些数据,但我无法让他们看到API。我也尝试了过来。通过' Guest.episodes。'就像我在内联管理员类的管理员那里有它,但没有改变任何东西。

1 个答案:

答案 0 :(得分:1)

您的"C""G""C""T""G""T""T""G""T""T"... 模型与您的EpisodeGuest模型没有任何远期关系。因此,您的Topic序列化程序应设法序列化Episodeguest_set,而不是topic_setguest

如果为这些M2M字段指定相关名称,则可以在此处自定义命名约定。现在你有这个:

topic

这意味着要访问与名为class Guest(models.Model): episodes = models.ManyToManyField(Episode) ... 的给定Guests相关联的所有Episode,反向查找将为ep。定义相关名称,您可以随意调用中间名:

ep.guest_set.all()

使用此功能,您可以使用class Guest(models.Model): episodes = models.ManyToManyField(Episode, related_name='guests') ... ,并且可以更新ep.guests.all()序列化程序以查找Episode而不是guests