Django-rest-framework嵌套url与drf-nested-routers

时间:2014-03-05 10:05:51

标签: django django-rest-framework drf-nested-routers

我正在使用drf-nested-routers包构建嵌套API。

然而/domains/1/nameservers/给了我所有的域名服务器,不仅仅是一个与域#1相关的名称服务器

我认为问题在于我使用默认教程NameServerViewSet实现

class NameserverViewSet(viewsets.ModelViewSet):
    queryset = Nameserver.objects.all()
    serializer_class = NameserverSerializer

请帮我正确编码。

以下是drf-nested-routers github page的示例。

drf-nested-routers提供嵌套路由器,用于生成

下面的url模式
  

\ domain \< - 域名列表\域{pk} \< - 一个域名,来自{pk]

     

\ domain {domain_pk} \ nameservers \< - 来自

的域名服务器      

{domain_pk} \ domain {domain_pk} \ nameservers \ {pk} \< - 来自{pk}的特定域名服务器,来自{domain_pk}

的域名

以下是一个例子:

# urls.py
from rest_framework_nested import routers
from views import DomainViewSet, NameserverViewSet
(...)

router = routers.SimpleRouter()
router.register(r'domains', DomainViewSet)

domains_router = routers.NestedSimpleRouter(router, r'domains', lookup='domain')
domains_router.register(r'nameservers', NameserverViewSet)

urlpatterns = patterns('',
    url(r'^', include(router.urls)),
    url(r'^', include(domains_router.urls)),
)

3 个答案:

答案 0 :(得分:8)

Solution来自作者Alan

以下是ViewSet的实现方式:

class NameserverViewSet(viewsets.ViewSet):
    queryset = Nameserver.objects.all()

    def list(self, request, domain_pk=None):
        queryset = self.queryset.filter(domain=domain_pk)
        serializer = NameserverSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None, domain_pk=None):
        queryset = self.queryset.get(pk=pk, domain=domain_pk)
        serializer = NameserverSerializer(queryset)
        return Response(serializer.data)

答案 1 :(得分:1)

@Artem,我在我的代码中使用了一个非常相似的解决方案。这是我做的:

我有一个叫做机构的实体。我为它创建了一条路线,如下所示:

router.register(r'institutions', SecurityViews.InstitutionViewSet, base_name='institutions')

我的网址如下:

http://127.0.0.1:8000/v1/institutions/
http://127.0.0.1:8000/v1/institutions/1/

第一个URL列出所有机构,第二个URL是详细信息URL。

现在,我有一些人,我想成为这些机构的成员。所以,对于路线,在urls.py上,我这样做了:

institutions_router = routers.NestedSimpleRouter(router, r'institutions', lookup='institution')

institutions_router.register(r'members', SecurityViews.InstitutionMemberViewSet, base_name='institution-members')

现在,我可以使用以下网址获取特定机构的成员:

http://127.0.0.1:8000/v1/institutions/1/members/

我还必须通过序列化程序定义关系,将主实体的pk映射到子实体。我不会在这里发布整个代码,因为我认为你熟悉这个概念。

对我来说,@ Artem提出的解决方案解决了我遇到的一个问题:返回过滤后的查询。现在工作正常。

我希望这会对你有所帮助。

答案 2 :(得分:0)

无需覆盖所有操作,您只需覆盖“ get_queryset()

class NameserverViewSet(viewsets.ViewSet):
    queryset = Nameserver.objects.all()

    def get_queryset(self):
        if self.kwargs.get('domain_pk'):
            return Nameserver.objects.filter(domain=domain_pk)
        else:
            return super(NameserverViewSet, self).get_queryset()