Skip to content

Commit

Permalink
Fixed #46 DetailSerializerMixin DRF 3.0 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Chibisov Gennady committed Nov 1, 2014
1 parent 60e4716 commit 30c8ce4
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 20 deletions.
4 changes: 3 additions & 1 deletion rest_framework_extensions/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ def get_rest_framework_features():
'django_object_permissions_class': get_rest_framework_version() >= (2, 3, 8),
'save_related_serializers': get_rest_framework_version() >= (2, 3, 8), # todo: test me
'write_only_fields': get_rest_framework_version() >= (2, 3, 11), # todo: test me
'get_object_has_queryset_argument': get_rest_framework_version() < (3, 0) # todo: test me
'has_action_and_link_decorators': get_rest_framework_version() < (3, 0), # todo: test me
'has_auto_writable_nested_serialization': get_rest_framework_version() < (3, 0), # todo: test me
'uses_single_request_data_in_serializers': get_rest_framework_version() >= (3, 0), # todo: test me
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
from rest_framework import serializers

from .models import KeyConstructorUserModel as UserModel


class UserModelSerializer(serializers.ModelSerializer):
class Meta:
model = UserModel
2 changes: 2 additions & 0 deletions tests_app/tests/functional/key_constructor/bits/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
from rest_framework.filters import DjangoFilterBackend

from .models import KeyConstructorUserModel as UserModel
from .serializers import UserModelSerializer


class UserModelViewSet(ListETAGMixin, RetrieveETAGMixin, viewsets.ModelViewSet):
queryset = UserModel.objects.all()
serializer_class = UserModelSerializer
filter_backends = (DjangoFilterBackend,)
filter_fields = ('property',)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
import django_filters
from rest_framework import viewsets
from rest_framework import viewsets, serializers
from rest_framework import filters
from rest_framework.permissions import DjangoModelPermissions
from rest_framework_extensions.mixins import ListDestroyModelMixin
Expand All @@ -16,9 +16,14 @@ class Meta:
]


class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment


class CommentViewSet(ListDestroyModelMixin, viewsets.ModelViewSet):
model = Comment
queryset = Comment.objects.all()
serializer_class = CommentSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_class = CommentFilter

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# -*- coding: utf-8 -*-
from rest_framework import serializers
from .models import UserForListUpdateModelMixin as User
from .models import (
UserForListUpdateModelMixin as User,
CommentForListUpdateModelMixin as Comment,
)


class UserSerializer(serializers.ModelSerializer):
Expand All @@ -16,4 +19,9 @@ class Meta:
'name',
'surname',
'password'
]
]


class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
CommentForListUpdateModelMixin as Comment,
UserForListUpdateModelMixin as User
)
from .serializers import UserSerializer
from .serializers import UserSerializer, CommentSerializer


class CommentFilter(django_filters.FilterSet):
Expand All @@ -21,8 +21,8 @@ class Meta:


class CommentViewSet(ListUpdateModelMixin, viewsets.ModelViewSet):
model = Comment
queryset = Comment.objects.all()
serializer_class = CommentSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_class = CommentFilter

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from rest_framework import viewsets
from rest_framework import viewsets, serializers
from rest_framework import authentication

try:
Expand Down Expand Up @@ -29,12 +29,17 @@ class CommentObjectPermissions(ExtendedDjangoObjectPermissions):
}


class PermissionsCommentSerializer(serializers.ModelSerializer):
class Meta:
model = PermissionsComment

class CommentObjectPermissionsWithoutHidingForbiddenObjects(CommentObjectPermissions):
hide_forbidden_for_read_objects = False


class CommentViewSet(viewsets.ModelViewSet):
model = PermissionsComment
queryset = PermissionsComment.objects.all()
serializer_class = PermissionsCommentSerializer
authentication_classes = [authentication.BasicAuthentication]
permission_classes = (CommentObjectPermissions,)

Expand Down
10 changes: 5 additions & 5 deletions tests_app/tests/functional/routers/nested_router_mixin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@


class UserViewSet(NestedViewSetMixin, ModelViewSet):
model = UserModel
queryset = UserModel.objects.all()
serializer_class = UserSerializer

@action(endpoint='users-list-action', is_for_list=True)
Expand All @@ -39,7 +39,7 @@ def users_action(self, request, *args, **kwargs):


class GroupViewSet(NestedViewSetMixin, ModelViewSet):
model = GroupModel
queryset = GroupModel.objects.all()
serializer_class = GroupSerializer

@link(endpoint='groups-list-link', is_for_list=True)
Expand All @@ -52,7 +52,7 @@ def groups_link(self, request, *args, **kwargs):


class PermissionViewSet(NestedViewSetMixin, ModelViewSet):
model = PermissionModel
queryset = PermissionModel.objects.all()
serializer_class = PermissionSerializer

@action(endpoint='permissions-list-action', is_for_list=True)
Expand All @@ -65,12 +65,12 @@ def permissions_action(self, request, *args, **kwargs):


class TaskViewSet(NestedViewSetMixin, ModelViewSet):
model = TaskModel
queryset = TaskModel.objects.all()
serializer_class = TaskSerializer


class BookViewSet(NestedViewSetMixin, ModelViewSet):
model = BookModel
queryset = BookModel.objects.all()
serializer_class = BookSerializer


Expand Down
6 changes: 6 additions & 0 deletions tests_app/tests/unit/routers/tests.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from django.test import TestCase
from django.utils import unittest

from rest_framework import viewsets
from rest_framework import decorators
from rest_framework.response import Response
from rest_framework_extensions.utils import get_rest_framework_features
from rest_framework_extensions.routers import ExtendedDefaultRouter
from rest_framework_extensions.decorators import link, action
from rest_framework_extensions.compat_drf import add_trailing_slash_if_needed
Expand Down Expand Up @@ -159,6 +161,10 @@ def action2(self, request, *args, **kwargs):
self.assertEqual(action1_list_route.name, u'{basename}-action-one-list')
self.assertEqual(action2_detail_route.name, u'{basename}-action-two')

@unittest.skipIf(
not get_rest_framework_features()['has_action_and_link_decorators'],
"Current DRF version has removed 'action' and 'link' decorators"
)
def test_with_default_controllers(self):
class BasicViewSet(viewsets.ViewSet):
@link()
Expand Down
2 changes: 1 addition & 1 deletion tests_app/tests/unit/serializers/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Meta(CommentSerializer.Meta):

class CommentSerializerWithExpandedUsersLiked(drf_serializers.PartialUpdateSerializerMixin,
serializers.ModelSerializer):
user = UserSerializer(source='user')
user = UserSerializer()

class Meta:
model = CommentModel
Expand Down
25 changes: 20 additions & 5 deletions tests_app/tests/unit/serializers/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,27 @@ def test_should_save_only_fields_from_data_for_partial_update(self):
# instance from arguments
serializer_one = CommentSerializer(instance=self.get_comment(), data={'title': 'goodbye'}, partial=True)
serializer_two = CommentSerializer(instance=self.get_comment(), data={'text': 'moon'}, partial=True)
serializer_three = CommentSerializer(instance=self.get_comment(),
data={},
files={'attachment': self.files[1]},
partial=True)
serializer_three_kwargs = {
'instance': self.get_comment(),
'partial': True
}
if get_rest_framework_features()['uses_single_request_data_in_serializers']:
serializer_three_kwargs['data'] = {'attachment': self.files[1]}
else:
serializer_three_kwargs.update({
'data': {},
'files': {'attachment': self.files[1]}
})
serializer_three = CommentSerializer(**serializer_three_kwargs)
self.assertTrue(serializer_one.is_valid())
self.assertTrue(serializer_two.is_valid())
self.assertTrue(serializer_three.is_valid())

# saving three serializers expecting they don't affect each other's saving
serializer_one.save()
serializer_two.save()
serializer_three.save()

fresh_instance = self.get_comment()
self.assertEqual(fresh_instance.attachment.read(), u'file two'.encode('utf-8'))
self.assertEqual(fresh_instance.text, 'moon')
Expand Down Expand Up @@ -181,6 +192,10 @@ def test_should_use_list_of_fields_to_update_from_arguments_if_it_passed(self):
self.assertEqual(fresh_instance.title, 'goodbye')
self.assertEqual(fresh_instance.text, 'world')

@unittest.skipUnless(
get_rest_framework_features()['has_auto_writable_nested_serialization'],
"This version of DRF doesn't have automatic writable nested serialization"
)
def test_should_not_use_update_fields_when_related_objects_are_saving(self):
data = {
'title': 'goodbye',
Expand All @@ -194,7 +209,7 @@ def test_should_not_use_update_fields_when_related_objects_are_saving(self):
self.assertTrue(serializer.is_valid())
try:
serializer.save()
except ValueError:
except ValueError as exc:
self.fail('If serializer has expanded related serializer, then it should not use update_fields while '
'saving related object')
fresh_instance = self.get_comment()
Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ envlist =
py27-drf2.4.0,
py27-drf2.4.1,
py27-drf2.4.2,
py27-drf3.0,
py3,
django1.5,
django1.6,
Expand Down

0 comments on commit 30c8ce4

Please sign in to comment.