【问题标题】:Django-rest-framework nested urls with drf-nested-routers带有 drf-nested-routers 的 Django-rest-framework 嵌套 url
【发布时间】:2014-04-07 07:39:13
【问题描述】:

我正在使用 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\

\domain{domain_pk}\nameservers\

{domain_pk} \domain{domain_pk}\nameservers\ {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)),
)

【问题讨论】:

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


    【解决方案1】:

    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)
    

    【讨论】:

    【解决方案2】:

    无需覆盖所有操作,只需覆盖“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()
    

    【讨论】:

    • domain_pk 似乎没有在这里定义
    【解决方案3】:

    @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/
    

    第一个网址列出所有机构,第二个是详细网址。

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

    institutions_router = routers.NestedSimpleRouter(router, r'institutions', lookup='institution')
    
    institutions_router.register(r'members', SecurityViews.InstitutionMemberViewSet, base_name='institution-members')
    

    现在,我可以通过以下 URL 获取特定机构的成员:

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

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

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

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2020-11-15
      • 2018-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多