mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-18 12:12:19 +03:00
Create individual mixins for update actions embedded in UpdateModelMixin
This commit is contained in:
parent
0f39e0124d
commit
f03100f0fb
|
@ -58,11 +58,8 @@ class RetrieveModelMixin:
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
class UpdateModelMixin:
|
class BaseUpdateModelMixin:
|
||||||
"""
|
def get_update_response(self, request, *args, **kwargs):
|
||||||
Update a model instance.
|
|
||||||
"""
|
|
||||||
def update(self, request, *args, **kwargs):
|
|
||||||
partial = kwargs.pop('partial', False)
|
partial = kwargs.pop('partial', False)
|
||||||
instance = self.get_object()
|
instance = self.get_object()
|
||||||
serializer = self.get_serializer(instance, data=request.data, partial=partial)
|
serializer = self.get_serializer(instance, data=request.data, partial=partial)
|
||||||
|
@ -82,6 +79,29 @@ class UpdateModelMixin:
|
||||||
def perform_update(self, serializer):
|
def perform_update(self, serializer):
|
||||||
serializer.save()
|
serializer.save()
|
||||||
|
|
||||||
|
|
||||||
|
class FullUpdateModelMixin(BaseUpdateModelMixin):
|
||||||
|
"""
|
||||||
|
Update a model instance. Only allowing 'PUT' method.
|
||||||
|
"""
|
||||||
|
def update(self, request, *args, **kwargs):
|
||||||
|
return self.get_update_response(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class PartialUpdateModelMixin(BaseUpdateModelMixin):
|
||||||
|
"""
|
||||||
|
Update a model instance. Only allowing 'PATCH' method.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def partial_update(self, request, *args, **kwargs):
|
||||||
|
kwargs['partial'] = True
|
||||||
|
return self.get_update_response(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateModelMixin(FullUpdateModelMixin, PartialUpdateModelMixin):
|
||||||
|
"""
|
||||||
|
Update a model instance. Allowing both 'PATCH' and 'PUT' methods.
|
||||||
|
"""
|
||||||
def partial_update(self, request, *args, **kwargs):
|
def partial_update(self, request, *args, **kwargs):
|
||||||
kwargs['partial'] = True
|
kwargs['partial'] = True
|
||||||
return self.update(request, *args, **kwargs)
|
return self.update(request, *args, **kwargs)
|
||||||
|
|
|
@ -6,8 +6,9 @@ from django.http import Http404
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from rest_framework import generics, renderers, serializers, status
|
from rest_framework import generics, mixins, renderers, serializers, status
|
||||||
from rest_framework.exceptions import ErrorDetail
|
from rest_framework.exceptions import ErrorDetail
|
||||||
|
from rest_framework.generics import GenericAPIView
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.test import APIRequestFactory
|
from rest_framework.test import APIRequestFactory
|
||||||
from tests.models import (
|
from tests.models import (
|
||||||
|
@ -63,6 +64,22 @@ class InstanceView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
serializer_class = BasicSerializer
|
serializer_class = BasicSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class PatchOnlyInstanceView(mixins.PartialUpdateModelMixin, GenericAPIView):
|
||||||
|
queryset = BasicModel.objects.exclude(text='filtered out')
|
||||||
|
serializer_class = BasicSerializer
|
||||||
|
|
||||||
|
def patch(self, request, *args, **kwargs):
|
||||||
|
return self.partial_update(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class PutOnlyInstanceView(mixins.FullUpdateModelMixin, GenericAPIView):
|
||||||
|
queryset = BasicModel.objects.exclude(text='filtered out')
|
||||||
|
serializer_class = BasicSerializer
|
||||||
|
|
||||||
|
def put(self, request, *args, **kwargs):
|
||||||
|
return self.update(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class FKInstanceView(generics.RetrieveUpdateDestroyAPIView):
|
class FKInstanceView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
queryset = ForeignKeySource.objects.all()
|
queryset = ForeignKeySource.objects.all()
|
||||||
serializer_class = ForeignKeySerializer
|
serializer_class = ForeignKeySerializer
|
||||||
|
@ -188,6 +205,8 @@ class TestInstanceView(TestCase):
|
||||||
]
|
]
|
||||||
self.view = InstanceView.as_view()
|
self.view = InstanceView.as_view()
|
||||||
self.slug_based_view = SlugBasedInstanceView.as_view()
|
self.slug_based_view = SlugBasedInstanceView.as_view()
|
||||||
|
self.patch_only_view = PatchOnlyInstanceView.as_view()
|
||||||
|
self.put_only_view = PutOnlyInstanceView.as_view()
|
||||||
|
|
||||||
def test_get_instance_view(self):
|
def test_get_instance_view(self):
|
||||||
"""
|
"""
|
||||||
|
@ -214,10 +233,11 @@ class TestInstanceView(TestCase):
|
||||||
"""
|
"""
|
||||||
PUT requests to RetrieveUpdateDestroyAPIView should update an object.
|
PUT requests to RetrieveUpdateDestroyAPIView should update an object.
|
||||||
"""
|
"""
|
||||||
|
for view in (self.view, self.put_only_view):
|
||||||
data = {'text': 'foobar'}
|
data = {'text': 'foobar'}
|
||||||
request = factory.put('/1', data, format='json')
|
request = factory.put('/1', data, format='json')
|
||||||
with self.assertNumQueries(EXPECTED_QUERIES_FOR_PUT):
|
with self.assertNumQueries(EXPECTED_QUERIES_FOR_PUT):
|
||||||
response = self.view(request, pk='1').render()
|
response = view(request, pk='1').render()
|
||||||
assert response.status_code == status.HTTP_200_OK
|
assert response.status_code == status.HTTP_200_OK
|
||||||
assert dict(response.data) == {'id': 1, 'text': 'foobar'}
|
assert dict(response.data) == {'id': 1, 'text': 'foobar'}
|
||||||
updated = self.objects.get(id=1)
|
updated = self.objects.get(id=1)
|
||||||
|
@ -227,11 +247,12 @@ class TestInstanceView(TestCase):
|
||||||
"""
|
"""
|
||||||
PATCH requests to RetrieveUpdateDestroyAPIView should update an object.
|
PATCH requests to RetrieveUpdateDestroyAPIView should update an object.
|
||||||
"""
|
"""
|
||||||
|
for view in (self.view, self.patch_only_view):
|
||||||
data = {'text': 'foobar'}
|
data = {'text': 'foobar'}
|
||||||
request = factory.patch('/1', data, format='json')
|
request = factory.patch('/1', data, format='json')
|
||||||
|
|
||||||
with self.assertNumQueries(EXPECTED_QUERIES_FOR_PUT):
|
with self.assertNumQueries(EXPECTED_QUERIES_FOR_PUT):
|
||||||
response = self.view(request, pk=1).render()
|
response = view(request, pk=1).render()
|
||||||
assert response.status_code == status.HTTP_200_OK
|
assert response.status_code == status.HTTP_200_OK
|
||||||
assert response.data == {'id': 1, 'text': 'foobar'}
|
assert response.data == {'id': 1, 'text': 'foobar'}
|
||||||
updated = self.objects.get(id=1)
|
updated = self.objects.get(id=1)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user