Django Rest Framework视图集从关系中删除嵌套资源

时间:2019-01-29 15:44:50

标签: python django rest django-rest-framework

我正在使用应用程序和服务器构建API。一个应用程序可以有许多服务器,而一个服务器可以有许多应用程序。

这些是我的模特。

class Server(Model):
    name = TextField(unique=True)
    description = TextField(blank=True)
    ip_address = TextField()

    class Meta:
        ordering = ["name"]

    def __str__(self):
        return self.name


class Application(Model):
    name = TextField(unique=True)
    description = TextField()
    is_critical = BooleanField()
    servers = ManyToManyField(Server, related_name="applications")

    class Meta:
        ordering = ["name"]

    def __str__(self):
        return self.name

这些是我的序列化器。

class ServerSerializer(ModelSerializer):

    class Meta:
        model = Server
        fields = "__all__"

class ApplicationSerializer(ModelSerializer):

    servers = ServerSerializer(many=True, read_only=True)    

    class Meta:
        model = Application
        fields = "__all__"

我正在使用DRF的视图集。

class ServerViewSet(ModelViewSet):
    queryset = Server.objects.all()
    serializer_class = ServerSerializer

class ApplicationViewSet(ModelViewSet):
    queryset = Application.objects.all()
    serializer_class = ApplicationSerializer

    @action(detail=True, methods=["HEAD", "GET", "POST", "DELETE"])
    def servers(self, request, pk=None):
        """Relate a server to the application"""

        application = self.get_object()

        if request.method in ("HEAD", "GET"):
            s_servers = ServerSerializer(application.servers, many=True)
            return Response(s_servers.data)
        else:
            server_id = request.data.get("id")
            if not server_id:
                return Response(
                    "Server details must be provided",
                    status=HTTP_400_BAD_REQUEST)

            server = get_object_or_404(Server, id=server_id)

            if request.method == "POST":
                application.servers.add(server)
                return Response(
                    "Server added to the application",
                    HTTP_201_CREATED)

            elif request.method == "DELETE":
                application.servers.remove(server)
                return Response(
                    "Server removed from the application",
                    HTTP_204_NO_CONTENT)

我希望服务器具有唯一性,并且应用程序可以具有许多服务器。因此,我将允许使用

访问服务器

/api/servers and /api/servers/<int:pk>

我希望用户使用来将现有服务器添加到他们的应用程序中

/api/applications/app_id/servers

除了删除已添加到应用程序中的服务器之外,我能够完成所有操作。如何使用嵌套资源的视图集处理删除HTTP请求?

1 个答案:

答案 0 :(得分:0)

您可以在ApplicationViewSet中使用destroy方法。

def destroy(self, request, *args, **kwargs):
    try:
        instance = self.get_object()
        instance.server.delete()
        self.perform_destroy(instance)
    except Http404:
        pass

    return Response(status=status.HTTP_204_NO_CONTENT)