This commit is contained in:
José Padilla 2015-07-20 18:56:33 +00:00
commit ee9b5dd9db
5 changed files with 41 additions and 2 deletions

View File

@ -447,6 +447,12 @@ An integer of 0 or more, that may be used to specify the number of application p
Default: `None` Default: `None`
#### SUPPORT_PATCH
If set to `False` then HTTP PATCH requests will not be allowed.
Default: `True`
[cite]: http://www.python.org/dev/peps/pep-0020/ [cite]: http://www.python.org/dev/peps/pep-0020/
[rfc4627]: http://www.ietf.org/rfc/rfc4627.txt [rfc4627]: http://www.ietf.org/rfc/rfc4627.txt
[heroku-minified-json]: https://github.com/interagent/http-api-design#keep-json-minified-in-all-responses [heroku-minified-json]: https://github.com/interagent/http-api-design#keep-json-minified-in-all-responses

View File

@ -6,7 +6,7 @@ which allows mixin classes to be composed in interesting ways.
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
from rest_framework import status from rest_framework import exceptions, status
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
@ -74,6 +74,9 @@ class UpdateModelMixin(object):
serializer.save() serializer.save()
def partial_update(self, request, *args, **kwargs): def partial_update(self, request, *args, **kwargs):
if not api_settings.SUPPORT_PATCH:
raise exceptions.MethodNotAllowed(request.method)
kwargs['partial'] = True kwargs['partial'] = True
return self.update(request, *args, **kwargs) return self.update(request, *args, **kwargs)

View File

@ -54,6 +54,7 @@ DEFAULTS = {
# Generic view behavior # Generic view behavior
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'DEFAULT_FILTER_BACKENDS': (), 'DEFAULT_FILTER_BACKENDS': (),
'SUPPORT_PATCH': True,
# Throttling # Throttling
'DEFAULT_THROTTLE_RATES': { 'DEFAULT_THROTTLE_RATES': {

View File

@ -129,7 +129,12 @@ class APIView(View):
""" """
Wrap Django's private `_allowed_methods` interface in a public property. 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 @property
def default_response_headers(self): def default_response_headers(self):

View File

@ -7,6 +7,7 @@ from django.test import TestCase
from django.utils import six from django.utils import six
from rest_framework import generics, renderers, serializers, status from rest_framework import generics, renderers, serializers, status
from rest_framework.settings import api_settings
from rest_framework.test import APIRequestFactory from rest_framework.test import APIRequestFactory
from tests.models import ( from tests.models import (
BasicModel, ForeignKeySource, ForeignKeyTarget, RESTFrameworkModel BasicModel, ForeignKeySource, ForeignKeyTarget, RESTFrameworkModel
@ -507,3 +508,26 @@ class TestFilterBackendAppliedToViews(TestCase):
response = view(request).render() response = view(request).render()
self.assertContains(response, 'field_b') self.assertContains(response, 'field_b')
self.assertNotContains(response, 'field_a') self.assertNotContains(response, 'field_a')
class TestSupportPatchSetting(TestCase):
def test_patch_instance_view_support_patch(self):
"""
PATCH requests should fail when SUPPORT_PATCH is set to False.
"""
obj = BasicModel.objects.create(text='abc')
class InstanceView(generics.UpdateAPIView):
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
api_settings.SUPPORT_PATCH = False
data = {'text': 'foobar'}
request = factory.patch('/1', data, format='json')
view = InstanceView.as_view()
response = view(request, pk=obj.pk).render()
api_settings.SUPPORT_PATCH = True
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)