更新:某些第三方软件包(drf-nested-routers和drf-extensions)似乎已解决此问题。有没有简单的方法用香草DRF做到这一点?
我正在试图弄清楚如何构建一个API,其中端点可以有额外的“边缘”,可用于查找相关对象,而不是在“端点”中包含那些相关对象(或它们的pks)。掌握“对象本身。当存在 lot 相关对象时,这可能很方便,因为在主对象的响应中包含相关对象会很昂贵。
这种API风格的一些例子是GitHub API和Facebook Graph API:
/repos/:owner/:repo/issues
=>获取与 repo
/v2.9/{photo-id}/likes
=>获取与照片
在下面的设计示例中,我认为list_route
中的ViewSet
可用于构建此类关系,但它会创建/repos/issues/
形式的网址而不是/repos/{pk}/issues/
。如果我将其更改为detail_route
,则会在网址中留下{pk}
,但这似乎是对detail_route
的滥用,因为这真的是要返回单个对象,对吗?
class Repo(models.Model):
name = models.TextField()
class Issue(models.Model):
title = models.TextField()
body = models.TextField()
repo = models.ForeignKey(Repo)
class RepoSerializer(serializers.ModelSerializer):
class Meta:
model = Repo
fields = ('pk', 'name')
# don't want to include all issues here, there might be a lot.
class IssueSerializer(serializers.ModelSerializer):
class Meta:
model = Issue
fields = ('pk', 'title', 'body')
class RepoViewSet(viewsets.ModelViewSet):
serializer_class = RepoSerializer
# THIS DOESN'T WORK! It creates:
# /repos/issues/ rather than /repos/{pk}/issues/
@list_route(serializer_class=IssueSerializer)
def issues(self):
repo = self.get_object()
issues = repo.issue_set.all()
s = self.get_serializer(issues, many=True)
return Response(s.data)
router.register(r'repos', RepoViewSet, base_name='repos')
我有什么想法可以从这个人那里获得/repos/{pk}/issues/
网址吗?
答案 0 :(得分:1)
没有理由detail_route
只返回单个实例,detail_route
是一个实例(详细信息视图)上的路由,但可能会返回相对于该实例的列表。
查看DRF docs的第二个示例:detail_route
装饰器用于返回列表。