pythondjangopython-3.xdjango-rest-frameworkdrf-nested-routers

Django REST Framework generics.RetrieveUpdateDestroyAPIView return all records instead of one


I'm new to DRF and trying to build a rest API, I have set up my models, URLs, views, and serializers as:

model.py:

services = (
    ('Single', 'Single'),
    ('Multiple', 'Multiple'),
)


class DeploymentOnUserModel(models.Model):
    deployment_name = models.CharField(max_length=256, )
    credentials = models.TextField(blank=False)
    project_name = models.CharField(max_length=150, blank=False)
    project_id = models.CharField(max_length=150, blank=True)
    cluster_name = models.CharField(max_length=256, blank=False)
    zone_region = models.CharField(max_length=150, blank=False)
    services = models.CharField(max_length=150, choices=services)
    configuration = models.TextField()
    routing = models.TextField()

    def save(self, **kwargs):
        if not self.id and self.services == 'Multiple' and not self.routing and not self.configuration:
            raise ValidationError("You must have to provide routing for multiple services deployment.")
        super().save(**kwargs)

From urls.py:

from django.urls import path, include
# from .routers import router
from . import apiview

app_name = 'deployments'

urlpatterns = [
    # path('', include(router.urls), name='deployments'),
    path('deployments/', apiview.DeploymentsList.as_view(), name='deployment-list'),
    path('deployments/<int:pk>/', apiview.DeploymentDetail.as_view(), name='deployment_detail')

]

From apiview.py:

class DeploymentDetail(generics.RetrieveUpdateDestroyAPIView):

    def retrieve(self, request, *args, **kwargs):
        pk = self.kwargs.get('pk')

        return Response(DeploymentOnUserModel.objects.get(pk=kwargs['pk']))

From serializers.py:

class DeploymentOnUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = DeploymentOnUserModel
        fields = '__all__'

When I try access: http://127.0.0.1:8000/api/v1/deployments/?pk=1/ it should return a single object of id=1 but it returns all objects.


Solution

  • Instead of pasing pk as GET argument you should pass it as part of url like this:

    http://127.0.0.1:8000/api/v1/deployments/1/ 
    

    URL you are trying to use http://127.0.0.1:8000/api/v1/deployments/?pk=1/ performed by DeploymentsList since it's not contain pk url kwarg.

    Also you should serialize object before return it as response:

    class DeploymentDetail(generics.RetrieveUpdateDestroyAPIView):
    
        def retrieve(self, request, *args, **kwargs):
            pk = self.kwargs.get('pk')
            object = DeploymentOnUserModel.objects.get(pk=kwargs['pk'])
            serializer = DeploymentOnUserSerializer(object)
            return Response(serializer.data)