mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-23 15:54:16 +03:00
adding test case for generic view with overriden get_object()
This commit is contained in:
parent
0c1b8b4f76
commit
750451f5b4
|
@ -24,6 +24,28 @@ class InstanceView(generics.RetrieveUpdateDestroyAPIView):
|
|||
model = BasicModel
|
||||
|
||||
|
||||
class InstanceDetailView(generics.RetrieveUpdateDestroyAPIView):
|
||||
"""
|
||||
Example detail view for override of get_object().
|
||||
"""
|
||||
|
||||
# we have to implement this too, otherwise we can't be sure that get_object
|
||||
# will be called
|
||||
def get_serializer(self, instance=None, data=None, files=None, partial=None):
|
||||
class InstanceDetailSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = BasicModel
|
||||
return InstanceDetailSerializer(instance=instance, data=data, files=files, partial=partial)
|
||||
|
||||
def get_object(self):
|
||||
try:
|
||||
pk = int(self.kwargs['pk'])
|
||||
self.object = BasicModel.objects.get(id=pk)
|
||||
return self.object
|
||||
except BasicModel.DoesNotExist:
|
||||
return self.permission_denied(self.request)
|
||||
|
||||
|
||||
class SlugSerializer(serializers.ModelSerializer):
|
||||
slug = serializers.Field() # read only
|
||||
|
||||
|
@ -301,6 +323,157 @@ class TestInstanceView(TestCase):
|
|||
new_obj = SlugBasedModel.objects.get(slug='test_slug')
|
||||
self.assertEqual(new_obj.text, 'foobar')
|
||||
|
||||
class TestInstanceDetailView(TestCase):
|
||||
"""
|
||||
Test cases for a RetrieveUpdateDestroyAPIView that does NOT use the
|
||||
queryset/model mechanism but instead overrides get_object()
|
||||
"""
|
||||
def setUp(self):
|
||||
"""
|
||||
Create 3 BasicModel intances.
|
||||
"""
|
||||
items = ['foo', 'bar', 'baz']
|
||||
for item in items:
|
||||
BasicModel(text=item).save()
|
||||
self.objects = BasicModel.objects
|
||||
self.data = [
|
||||
{'id': obj.id, 'text': obj.text}
|
||||
for obj in self.objects.all()
|
||||
]
|
||||
self.view_class = InstanceDetailView
|
||||
self.view = InstanceDetailView.as_view()
|
||||
|
||||
def test_get_instance_view(self):
|
||||
"""
|
||||
GET requests to RetrieveUpdateDestroyAPIView should return a single object.
|
||||
"""
|
||||
request = factory.get('/1')
|
||||
with self.assertNumQueries(1):
|
||||
response = self.view(request, pk=1).render()
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data, self.data[0])
|
||||
|
||||
def test_post_instance_view(self):
|
||||
"""
|
||||
POST requests to RetrieveUpdateDestroyAPIView should not be allowed
|
||||
"""
|
||||
content = {'text': 'foobar'}
|
||||
request = factory.post('/', json.dumps(content),
|
||||
content_type='application/json')
|
||||
with self.assertNumQueries(0):
|
||||
response = self.view(request).render()
|
||||
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
|
||||
self.assertEqual(response.data, {"detail": "Method 'POST' not allowed."})
|
||||
|
||||
def test_put_instance_view(self):
|
||||
"""
|
||||
PUT requests to RetrieveUpdateDestroyAPIView should update an object.
|
||||
"""
|
||||
content = {'text': 'foobar'}
|
||||
request = factory.put('/1', json.dumps(content),
|
||||
content_type='application/json')
|
||||
with self.assertNumQueries(2):
|
||||
response = self.view(request, pk='1').render()
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data, {'id': 1, 'text': 'foobar'})
|
||||
updated = self.objects.get(id=1)
|
||||
self.assertEqual(updated.text, 'foobar')
|
||||
|
||||
def test_patch_instance_view(self):
|
||||
"""
|
||||
PATCH requests to RetrieveUpdateDestroyAPIView should update an object.
|
||||
"""
|
||||
content = {'text': 'foobar'}
|
||||
request = factory.patch('/1', json.dumps(content),
|
||||
content_type='application/json')
|
||||
|
||||
with self.assertNumQueries(2):
|
||||
response = self.view(request, pk=1).render()
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data, {'id': 1, 'text': 'foobar'})
|
||||
updated = self.objects.get(id=1)
|
||||
self.assertEqual(updated.text, 'foobar')
|
||||
|
||||
def test_delete_instance_view(self):
|
||||
"""
|
||||
DELETE requests to RetrieveUpdateDestroyAPIView should delete an object.
|
||||
"""
|
||||
request = factory.delete('/1')
|
||||
with self.assertNumQueries(2):
|
||||
response = self.view(request, pk=1).render()
|
||||
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
||||
self.assertEqual(response.content, six.b(''))
|
||||
ids = [obj.id for obj in self.objects.all()]
|
||||
self.assertEqual(ids, [2, 3])
|
||||
|
||||
def test_options_instance_view(self):
|
||||
"""
|
||||
OPTIONS requests to RetrieveUpdateDestroyAPIView should return metadata
|
||||
"""
|
||||
request = factory.options('/')
|
||||
with self.assertNumQueries(0):
|
||||
response = self.view(request).render()
|
||||
expected = {
|
||||
'parses': [
|
||||
'application/json',
|
||||
'application/x-www-form-urlencoded',
|
||||
'multipart/form-data'
|
||||
],
|
||||
'renders': [
|
||||
'application/json',
|
||||
'text/html'
|
||||
],
|
||||
'name': 'Instance Detail',
|
||||
'description': 'Example detail view for override of get_object().'
|
||||
}
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data, expected)
|
||||
|
||||
def test_put_cannot_set_id(self):
|
||||
"""
|
||||
PUT requests to create a new object should not be able to set the id.
|
||||
"""
|
||||
content = {'id': 999, 'text': 'foobar'}
|
||||
request = factory.put('/1', json.dumps(content),
|
||||
content_type='application/json')
|
||||
with self.assertNumQueries(2):
|
||||
response = self.view(request, pk=1).render()
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data, {'id': 1, 'text': 'foobar'})
|
||||
updated = self.objects.get(id=1)
|
||||
self.assertEqual(updated.text, 'foobar')
|
||||
|
||||
def test_put_to_deleted_instance(self):
|
||||
"""
|
||||
PUT requests to RetrieveUpdateDestroyAPIView should create an object
|
||||
if it does not currently exist. In our DetailView, however,
|
||||
we cannot access any other id's than those that already exist.
|
||||
See the InstanceView for the normal behaviour.
|
||||
"""
|
||||
self.objects.get(id=1).delete()
|
||||
content = {'text': 'foobar'}
|
||||
request = factory.put('/1', json.dumps(content),
|
||||
content_type='application/json')
|
||||
with self.assertNumQueries(1):
|
||||
response = self.view(request, pk=5).render()
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
def test_put_as_create_on_id_based_url(self):
|
||||
"""
|
||||
PUT requests to RetrieveUpdateDestroyAPIView should create an object
|
||||
at the requested url if it doesn't exist. In our DetailView, however,
|
||||
we cannot access any other id's than those that already exist.
|
||||
See the InstanceView for the normal behaviour.
|
||||
"""
|
||||
content = {'text': 'foobar'}
|
||||
# pk fields can not be created on demand, only the database can set the pk for a new object
|
||||
request = factory.put('/5', json.dumps(content),
|
||||
content_type='application/json')
|
||||
with self.assertNumQueries(1):
|
||||
response = self.view(request, pk=5).render()
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
|
||||
|
||||
# Regression test for #285
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user