diff options
Diffstat (limited to 'rest_framework/tests/generics.py')
| -rw-r--r-- | rest_framework/tests/generics.py | 105 | 
1 files changed, 86 insertions, 19 deletions
diff --git a/rest_framework/tests/generics.py b/rest_framework/tests/generics.py index f564890c..15d87e86 100644 --- a/rest_framework/tests/generics.py +++ b/rest_framework/tests/generics.py @@ -1,7 +1,8 @@  from __future__ import unicode_literals  from django.db import models +from django.shortcuts import get_object_or_404  from django.test import TestCase -from rest_framework import generics, serializers, status +from rest_framework import generics, renderers, serializers, status  from rest_framework.tests.utils import RequestFactory  from rest_framework.tests.models import BasicModel, Comment, SlugBasedModel  from rest_framework.compat import six @@ -38,6 +39,7 @@ class SlugBasedInstanceView(InstanceView):      """      model = SlugBasedModel      serializer_class = SlugSerializer +    lookup_field = 'slug'  class TestRootView(TestCase): @@ -302,6 +304,47 @@ class TestInstanceView(TestCase):          self.assertEqual(new_obj.text, 'foobar') +class TestOverriddenGetObject(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() +        ] + +        class OverriddenGetObjectView(generics.RetrieveUpdateDestroyAPIView): +            """ +            Example detail view for override of get_object(). +            """ +            model = BasicModel + +            def get_object(self): +                pk = int(self.kwargs['pk']) +                return get_object_or_404(BasicModel.objects.all(), id=pk) + +        self.view = OverriddenGetObjectView.as_view() + +    def test_overridden_get_object_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]) + +  # Regression test for #285  class CommentSerializer(serializers.ModelSerializer): @@ -335,7 +378,7 @@ class TestCreateModelWithAutoNowAddField(TestCase):          self.assertEqual(created.content, 'foobar') -# Test for particularly ugly regression with m2m in browseable API +# Test for particularly ugly regression with m2m in browsable API  class ClassB(models.Model):      name = models.CharField(max_length=255) @@ -360,7 +403,7 @@ class ExampleView(generics.ListCreateAPIView):  class TestM2MBrowseableAPI(TestCase):      def test_m2m_in_browseable_api(self):          """ -        Test for particularly ugly regression with m2m in browseable API +        Test for particularly ugly regression with m2m in browsable API          """          request = factory.get('/', HTTP_ACCEPT='text/html')          view = ExampleView().as_view() @@ -392,22 +435,14 @@ class TestFilterBackendAppliedToViews(TestCase):              {'id': obj.id, 'text': obj.text}              for obj in self.objects.all()          ] -        self.root_view = RootView.as_view() -        self.instance_view = InstanceView.as_view() -        self.original_root_backend = getattr(RootView, 'filter_backend') -        self.original_instance_backend = getattr(InstanceView, 'filter_backend') - -    def tearDown(self): -        setattr(RootView, 'filter_backend', self.original_root_backend) -        setattr(InstanceView, 'filter_backend', self.original_instance_backend)      def test_get_root_view_filters_by_name_with_filter_backend(self):          """          GET requests to ListCreateAPIView should return filtered list.          """ -        setattr(RootView, 'filter_backend', InclusiveFilterBackend) +        root_view = RootView.as_view(filter_backends=(InclusiveFilterBackend,))          request = factory.get('/') -        response = self.root_view(request).render() +        response = root_view(request).render()          self.assertEqual(response.status_code, status.HTTP_200_OK)          self.assertEqual(len(response.data), 1)          self.assertEqual(response.data, [{'id': 1, 'text': 'foo'}]) @@ -416,9 +451,9 @@ class TestFilterBackendAppliedToViews(TestCase):          """          GET requests to ListCreateAPIView should return empty list when all models are filtered out.          """ -        setattr(RootView, 'filter_backend', ExclusiveFilterBackend) +        root_view = RootView.as_view(filter_backends=(ExclusiveFilterBackend,))          request = factory.get('/') -        response = self.root_view(request).render() +        response = root_view(request).render()          self.assertEqual(response.status_code, status.HTTP_200_OK)          self.assertEqual(response.data, []) @@ -426,9 +461,9 @@ class TestFilterBackendAppliedToViews(TestCase):          """          GET requests to RetrieveUpdateDestroyAPIView should raise 404 when model filtered out.          """ -        setattr(InstanceView, 'filter_backend', ExclusiveFilterBackend) +        instance_view = InstanceView.as_view(filter_backends=(ExclusiveFilterBackend,))          request = factory.get('/1') -        response = self.instance_view(request, pk=1).render() +        response = instance_view(request, pk=1).render()          self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)          self.assertEqual(response.data, {'detail': 'Not found'}) @@ -436,8 +471,40 @@ class TestFilterBackendAppliedToViews(TestCase):          """          GET requests to RetrieveUpdateDestroyAPIView should return a single object when not excluded          """ -        setattr(InstanceView, 'filter_backend', InclusiveFilterBackend) +        instance_view = InstanceView.as_view(filter_backends=(InclusiveFilterBackend,))          request = factory.get('/1') -        response = self.instance_view(request, pk=1).render() +        response = instance_view(request, pk=1).render()          self.assertEqual(response.status_code, status.HTTP_200_OK)          self.assertEqual(response.data, {'id': 1, 'text': 'foo'}) + + +class TwoFieldModel(models.Model): +    field_a = models.CharField(max_length=100) +    field_b = models.CharField(max_length=100) + + +class DynamicSerializerView(generics.ListCreateAPIView): +    model = TwoFieldModel +    renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer) + +    def get_serializer_class(self): +        if self.request.method == 'POST': +            class DynamicSerializer(serializers.ModelSerializer): +                class Meta: +                    model = TwoFieldModel +                    fields = ('field_b',) +            return DynamicSerializer +        return super(DynamicSerializerView, self).get_serializer_class() + + +class TestFilterBackendAppliedToViews(TestCase): + +    def test_dynamic_serializer_form_in_browsable_api(self): +        """ +        GET requests to ListCreateAPIView should return filtered list. +        """ +        view = DynamicSerializerView.as_view() +        request = factory.get('/') +        response = view(request).render() +        self.assertContains(response, 'field_b') +        self.assertNotContains(response, 'field_a')  | 
