【问题标题】:Django Rest Framework: How to implement a nested logic?Django Rest Framework:如何实现嵌套逻辑?
【发布时间】:2018-09-05 14:02:04
【问题描述】:

假设我有三个模型:

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

我的 serializers.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')

views.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

urls.py:

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 框架的新手。上述类只是一个示例。忽略错误。

【问题讨论】:

    标签: python django django-models django-rest-framework django-views


    【解决方案1】:

    您应该为您的视图集使用@list_route@detail_route 的django 装饰器。但请注意您的 DRF 版本。因为这些装饰器在 DRF 3.8+ 中合并为@action。这是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/
    

    您可以在此处从documentation 找到有关@actions 的更多详细信息。

    PS:不要忘记控制代码中的空实体结果。您应该使用正确的状态代码返回正确的响应。

    【讨论】:

      猜你喜欢
      • 2015-12-16
      • 2017-04-08
      • 1970-01-01
      • 1970-01-01
      • 2023-01-08
      • 2019-02-19
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      相关资源
      最近更新 更多