Flexible implementation for SUPPORT_PATCH

This commit is contained in:
José Padilla 2015-06-26 10:31:50 -04:00 committed by José Padilla
parent b428a6cafd
commit 1402f51327
3 changed files with 32 additions and 27 deletions

View File

@ -229,8 +229,9 @@ class UpdateAPIView(mixins.UpdateModelMixin,
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
if api_settings.SUPPORT_PATCH:
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
class ListCreateAPIView(mixins.ListModelMixin,
@ -258,8 +259,9 @@ class RetrieveUpdateAPIView(mixins.RetrieveModelMixin,
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
if api_settings.SUPPORT_PATCH:
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
class RetrieveDestroyAPIView(mixins.RetrieveModelMixin,
@ -288,8 +290,9 @@ class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
if api_settings.SUPPORT_PATCH:
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)

View File

@ -129,12 +129,7 @@ class APIView(View):
"""
Wrap Django's private `_allowed_methods` interface in a public property.
"""
allowed_methods = self._allowed_methods()
if not api_settings.SUPPORT_PATCH and 'PATCH' in allowed_methods:
allowed_methods.remove('PATCH')
return allowed_methods
return self._allowed_methods()
@property
def default_response_headers(self):
@ -456,7 +451,7 @@ class APIView(View):
self.initial(request, *args, **kwargs)
# Get the appropriate handler method
if request.method in self.allowed_methods:
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:

View File

@ -4,10 +4,11 @@ import django
from django.db import models
from django.shortcuts import get_object_or_404
from django.test import TestCase
from django.test.utils import override_settings
from django.utils import six
from django.utils.six.moves import reload_module
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
@ -214,19 +215,6 @@ 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.
@ -521,3 +509,22 @@ class TestFilterBackendAppliedToViews(TestCase):
response = view(request).render()
self.assertContains(response, 'field_b')
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.
"""
with override_settings(REST_FRAMEWORK={'SUPPORT_PATCH': False}):
reload_module(generics)
data = {'text': 'foobar'}
request = factory.patch('/1', data, format='json')
class InstanceView(generics.UpdateAPIView):
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
view = InstanceView.as_view()
response = view(request, pk=1).render()
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)