Difference between patch at /product/ vs /product/{id} Django Rest Framework

I am trying to make a project, which allows creating a patching a product model.

Everything works fine according to all my code when I put the patch request for that object at /product/ Payload tried : { "id": 46, "name": "DBZ", "created": "2022-12-08T12:48:48.232455Z", "max_nodes": 22, "allowed": false } And I get validation field 422 error with "detail": "Please enter only the whitelisted fields" which is expected.

But when I put patch request in /product/46 with payload: { "name": "DBZ", "created": "2022-12-08T12:48:48.232455Z", "max_nodes": 22, "allowed": false } I get a 200 OK message and the object with that id gets patched.

I am new to this DRF, can someone let me know what is happening here.

models.py

class Product(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    name = models.CharField(max_length=256)
    max_nodes = models.IntegerField()
    allowed = models.BooleanField(default=False)
    auto_delete = models.BooleanField(default=False)
    
    def __str__(self):
        """
        The string to represent this object.
        We use the name field to provide a reasonable value
        in the Admin pages.
        """
        return self.name

serializers.py

class ProductSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Product
        fields = ('id', 'name', 'created', 'max_nodes', 'allowed', 'auto_delete')

views.py

class ProductViewSet(viewsets.ModelViewSet):
    """
    API Endpoint that allows patching product objects
    """
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

    def create(self, request):
        if request.user.is_anonymous:
            logger.warning("ANONYMOUS USER!")
            raise PermissionDenied()
        serializer = ProductSerializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)
    
     def patch(self, request):
        if not request.user.is_superuser:
            logger.warning("Not a superuser")
            raise PermissionDenied()
        instance = Product.objects.get(id=request.data['id'])
        all_fields = ['id', 'name', 'created', 'max_nodes', 'allowed', 'auto_delete']
        whitelisted_fields = ['name', 'max_nodes', 'allowed', 'auto_delete']
        extra_fields = [key for key in list(request.data.keys()) if key not in whitelisted_fields and key != "id"]
        if len(extra_fields) > 0:
            return Response({"Please enter only the whitelisted fields"},
                                status=status.HTTP_422_UNPROCESSABLE_ENTITY)

        # Get all fields
        sanitized_data = {}
        for field in all_fields:
            if field in request.data:
                sanitized_data[field] = request.data[field]
            else:
                sanitized_data[field] = getattr(instance, field)

        serializer = ProductSerializer(instance=instance, data=sanitized_data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

urls.py

router.register(r'products', ProductViewSet, basename='product')

Can someone please help in this?

I tried to patch the objects in both way, currently nothing productive found. Asking for help/instructions here.

Back to Top