From b428a6cafd18072cf457a751be2becb616c3b099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Padilla?= Date: Fri, 26 Jun 2015 10:03:17 -0400 Subject: [PATCH] Implement SUPPORT_PATCH setting --- rest_framework/settings.py | 1 + rest_framework/views.py | 9 +++++++-- tests/test_generics.py | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 4c46a4831..6dfd573a1 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -54,6 +54,7 @@ DEFAULTS = { # Generic view behavior 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'DEFAULT_FILTER_BACKENDS': (), + 'SUPPORT_PATCH': True, # Throttling 'DEFAULT_THROTTLE_RATES': { diff --git a/rest_framework/views.py b/rest_framework/views.py index a709c2f6b..faa197e1e 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -129,7 +129,12 @@ class APIView(View): """ Wrap Django's private `_allowed_methods` interface in a public property. """ - return self._allowed_methods() + allowed_methods = self._allowed_methods() + + if not api_settings.SUPPORT_PATCH and 'PATCH' in allowed_methods: + allowed_methods.remove('PATCH') + + return allowed_methods @property def default_response_headers(self): @@ -451,7 +456,7 @@ class APIView(View): self.initial(request, *args, **kwargs) # Get the appropriate handler method - if request.method.lower() in self.http_method_names: + if request.method in self.allowed_methods: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: diff --git a/tests/test_generics.py b/tests/test_generics.py index 0647119bf..d98c86dea 100644 --- a/tests/test_generics.py +++ b/tests/test_generics.py @@ -7,6 +7,7 @@ from django.test import TestCase from django.utils import six from rest_framework import generics, renderers, serializers, status +from rest_framework.settings import api_settings from rest_framework.test import APIRequestFactory from tests.models import ( BasicModel, ForeignKeySource, ForeignKeyTarget, RESTFrameworkModel @@ -213,6 +214,19 @@ class TestInstanceView(TestCase): updated = self.objects.get(id=1) self.assertEqual(updated.text, 'foobar') + def test_patch_instance_view_support_patch(self): + """ + PATCH requests with SUPPORT_PATCH=False should return 405 + """ + data = {'text': 'foobar'} + request = factory.patch('/1', data, format='json') + + api_settings.SUPPORT_PATCH = False + response = self.view(request, pk=1).render() + api_settings.SUPPORT_PATCH = True + + self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) + def test_delete_instance_view(self): """ DELETE requests to RetrieveUpdateDestroyAPIView should delete an object.