代码之家  ›  专栏  ›  技术社区  ›  Sreekanth Reddy Balne

Django Rest框架:如何实现嵌套逻辑?

  •  0
  • Sreekanth Reddy Balne  · 技术社区  · 6 年前

    假设我有三个模型:

    class User(AppModel):
        name = models.CharField(max_length=255)
    
    class Business(AppModel):
        owner = models.ForeignKey("User", related_name="businesses", on_delete=models.CASCADE)
        legal_name = models.CharField(max_length=255)
    
    class Invoice(AppModel):
        business = models.ForeignKey("Business", related_name="invoices", on_delete=models.CASCADE)
        amount = models.integerField()
    

    如你所见,一个 user 可以有多个 businesses 和一个 business 可以有多个 invoices

    我的序列化程序.py:

    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields= ('name')
    
    class BusinessSerializer(serializers.ModelSerializer):
        owner = UserSerializer(many=False)
        class Meta:
            model = Business
            fields= ('owner','legal_name')
    
    class InvoiceSerializer(serializers.ModelSerializer):
        business= BusinessSerializer(many=False)
        class Meta:
            model = Invoice
            fields= ('business','amount')
    

    视图.py:

    class UserViewSet(viewsets.ModelViewSet):
        queryset = User.objects.all()
        serializer_class = UserSerializer
    
    class BusinessViewSet(viewsets.ModelViewSet):
        queryset = Business.objects.all()
        serializer_class = BusinessSerializer
    
    class InvoiceViewSet(viewsets.ModelViewSet):
        queryset = Invoice.objects.all()
        serializer_class = InvoiceSerializer
    

    router = DefaultRouter()
    router.register('user', UserViewSet, base_name='users')
    router.register('business', BusinessViewSet, base_name='businesses')
    router.register('invoice', InvoiceViewSet, base_name='invoices')
    urlpatterns = router.urls
    

    http://example.com/api/user 返回所有用户。没问题。

    • http://example.com/api/business/ 退货

      [ { "legal_name": "1business", "owner": 1, }, { "legal_name": "2business", "owner": 1, },]

    • http://example.com/api/business/1/ 退货

      { "legal_name": "1business", "owner": 1, }

    以上都可以。但我也需要:

    • http://example.com/api/business/1/invoices/

      [ { "business": 1, "amount": 100, }, { "business": 1, "amount": 999, },]

    以及我应该能够创建更新删除这些发票那里。

    有什么帮助吗?我是django rest框架的新手。以上的课程只是一个例子。忽略错误。

    2 回复  |  直到 6 年前
        1
  •  0
  •   uedemir    6 年前

    你应该使用django装饰器 @list_route @detail_route 为您的视图集。但是要小心你的DRF版本。因为那些装饰师合并成了 @action 在DRF 3.8+中。这是你的名字 announcement .

    from rest_framework.decorators import action
    from rest_framework.response import Response
    from rest_framework import status
    
    
    class BusinessViewSet(viewsets.ModelViewSet):
        queryset = Business.objects.all()
        serializer_class = BusinessSerializer
    
        @action(detail=True, methods=["GET"], url_path="invoices")
        def invoices(self, request, pk=None):
            """
             Your codes comes here to return related result.
             pk variable contains the param value from url.
             if you do not specify the url_path properties then action will accept the function's name as url path.
            """
            entity = Invoice.objects.filter(business=pk)
            serializer = self.get_serializer(entity, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)
    

    http://example.com/api/business/{{PK}}/invoices/
    http://example.com/api/business/1/invoices/
    http://example.com/api/business/3/invoices/
    http://example.com/api/business/23/invoices/
    

    @actions 从…起 documentation

    别忘了在代码中控制空实体结果。您应该返回正确的响应和正确的状态代码。