Remove .model usage in tests.

Remove the shortcut `.model` view attribute usage from test cases.
This commit is contained in:
Tom Christie 2014-08-29 12:35:53 +01:00
parent b8c8d10a18
commit b3253b4283
11 changed files with 185 additions and 118 deletions

View File

@ -51,11 +51,6 @@ class GenericAPIView(views.APIView):
queryset = None
serializer_class = None
# This shortcut may be used instead of setting either or both
# of the `queryset`/`serializer_class` attributes, although using
# the explicit style is generally preferred.
model = None
# If you want to use object lookups other than pk, set this attribute.
# For more complex lookup requirements override `get_object()`.
lookup_field = 'pk'
@ -71,9 +66,8 @@ class GenericAPIView(views.APIView):
# The filter backend classes to use for queryset filtering
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
# The following attributes may be subject to change,
# The following attribute may be subject to change,
# and should be considered private API.
model_serializer_class = api_settings.DEFAULT_MODEL_SERIALIZER_CLASS
paginator_class = Paginator
def get_serializer_context(self):
@ -199,26 +193,13 @@ class GenericAPIView(views.APIView):
(Eg. admins get full serialization, others get basic serialization)
"""
serializer_class = self.serializer_class
if serializer_class is not None:
return serializer_class
warnings.warn(
'The `.model` attribute on view classes is now deprecated in favor '
'of the more explicit `serializer_class` and `queryset` attributes.',
DeprecationWarning, stacklevel=2
assert self.serializer_class is not None, (
"'%s' should either include a `serializer_class` attribute, "
"or override the `get_serializer_class()` method."
% self.__class__.__name__
)
assert self.model is not None, \
"'%s' should either include a 'serializer_class' attribute, " \
"or use the 'model' attribute as a shortcut for " \
"automatically generating a serializer class." \
% self.__class__.__name__
class DefaultSerializer(self.model_serializer_class):
class Meta:
model = self.model
return DefaultSerializer
return self.serializer_class
def get_queryset(self):
"""
@ -235,19 +216,13 @@ class GenericAPIView(views.APIView):
(Eg. return a list of items that is specific to the user)
"""
if self.queryset is not None:
return self.queryset._clone()
assert self.queryset is not None, (
"'%s' should either include a `queryset` attribute, "
"or override the `get_queryset()` method."
% self.__class__.__name__
)
if self.model is not None:
warnings.warn(
'The `.model` attribute on view classes is now deprecated in favor '
'of the more explicit `serializer_class` and `queryset` attributes.',
DeprecationWarning, stacklevel=2
)
return self.model._default_manager.all()
error_format = "'%s' must define 'queryset' or 'model'"
raise ImproperlyConfigured(error_format % self.__class__.__name__)
return self.queryset._clone()
def get_object(self):
"""

View File

@ -1,7 +0,0 @@
from rest_framework import serializers
from tests.models import NullableForeignKeySource
class NullableFKSourceSerializer(serializers.ModelSerializer):
class Meta:
model = NullableForeignKeySource

View File

@ -16,9 +16,14 @@ factory = APIRequestFactory()
if django_filters:
class FilterableItemSerializer(serializers.ModelSerializer):
class Meta:
model = FilterableItem
# Basic filter on a list view.
class FilterFieldsRootView(generics.ListCreateAPIView):
model = FilterableItem
queryset = FilterableItem.objects.all()
serializer_class = FilterableItemSerializer
filter_fields = ['decimal', 'date']
filter_backends = (filters.DjangoFilterBackend,)
@ -33,7 +38,8 @@ if django_filters:
fields = ['text', 'decimal', 'date']
class FilterClassRootView(generics.ListCreateAPIView):
model = FilterableItem
queryset = FilterableItem.objects.all()
serializer_class = FilterableItemSerializer
filter_class = SeveralFieldsFilter
filter_backends = (filters.DjangoFilterBackend,)
@ -46,12 +52,14 @@ if django_filters:
fields = ['text']
class IncorrectlyConfiguredRootView(generics.ListCreateAPIView):
model = FilterableItem
queryset = FilterableItem.objects.all()
serializer_class = FilterableItemSerializer
filter_class = MisconfiguredFilter
filter_backends = (filters.DjangoFilterBackend,)
class FilterClassDetailView(generics.RetrieveAPIView):
model = FilterableItem
queryset = FilterableItem.objects.all()
serializer_class = FilterableItemSerializer
filter_class = SeveralFieldsFilter
filter_backends = (filters.DjangoFilterBackend,)
@ -63,15 +71,12 @@ if django_filters:
model = BaseFilterableItem
class BaseFilterableItemFilterRootView(generics.ListCreateAPIView):
model = FilterableItem
queryset = FilterableItem.objects.all()
serializer_class = FilterableItemSerializer
filter_class = BaseFilterableItemFilter
filter_backends = (filters.DjangoFilterBackend,)
# Regression test for #814
class FilterableItemSerializer(serializers.ModelSerializer):
class Meta:
model = FilterableItem
class FilterFieldsQuerysetView(generics.ListCreateAPIView):
queryset = FilterableItem.objects.all()
serializer_class = FilterableItemSerializer
@ -323,6 +328,11 @@ class SearchFilterModel(models.Model):
text = models.CharField(max_length=100)
class SearchFilterSerializer(serializers.ModelSerializer):
class Meta:
model = SearchFilterModel
class SearchFilterTests(TestCase):
def setUp(self):
# Sequence of title/text is:
@ -342,7 +352,8 @@ class SearchFilterTests(TestCase):
def test_search(self):
class SearchListView(generics.ListAPIView):
model = SearchFilterModel
queryset = SearchFilterModel.objects.all()
serializer_class = SearchFilterSerializer
filter_backends = (filters.SearchFilter,)
search_fields = ('title', 'text')
@ -359,7 +370,8 @@ class SearchFilterTests(TestCase):
def test_exact_search(self):
class SearchListView(generics.ListAPIView):
model = SearchFilterModel
queryset = SearchFilterModel.objects.all()
serializer_class = SearchFilterSerializer
filter_backends = (filters.SearchFilter,)
search_fields = ('=title', 'text')
@ -375,7 +387,8 @@ class SearchFilterTests(TestCase):
def test_startswith_search(self):
class SearchListView(generics.ListAPIView):
model = SearchFilterModel
queryset = SearchFilterModel.objects.all()
serializer_class = SearchFilterSerializer
filter_backends = (filters.SearchFilter,)
search_fields = ('title', '^text')
@ -392,7 +405,8 @@ class SearchFilterTests(TestCase):
def test_search_with_nonstandard_search_param(self):
with temporary_setting('SEARCH_PARAM', 'query', module=filters):
class SearchListView(generics.ListAPIView):
model = SearchFilterModel
queryset = SearchFilterModel.objects.all()
serializer_class = SearchFilterSerializer
filter_backends = (filters.SearchFilter,)
search_fields = ('title', 'text')
@ -418,6 +432,11 @@ class OrderingFilterRelatedModel(models.Model):
related_name="relateds")
class OrderingFilterSerializer(serializers.ModelSerializer):
class Meta:
model = OrdringFilterModel
class OrderingFilterTests(TestCase):
def setUp(self):
# Sequence of title/text is:
@ -440,7 +459,8 @@ class OrderingFilterTests(TestCase):
def test_ordering(self):
class OrderingListView(generics.ListAPIView):
model = OrdringFilterModel
queryset = OrdringFilterModel.objects.all()
serializer_class = OrderingFilterSerializer
filter_backends = (filters.OrderingFilter,)
ordering = ('title',)
ordering_fields = ('text',)
@ -459,7 +479,8 @@ class OrderingFilterTests(TestCase):
def test_reverse_ordering(self):
class OrderingListView(generics.ListAPIView):
model = OrdringFilterModel
queryset = OrdringFilterModel.objects.all()
serializer_class = OrderingFilterSerializer
filter_backends = (filters.OrderingFilter,)
ordering = ('title',)
ordering_fields = ('text',)
@ -478,7 +499,8 @@ class OrderingFilterTests(TestCase):
def test_incorrectfield_ordering(self):
class OrderingListView(generics.ListAPIView):
model = OrdringFilterModel
queryset = OrdringFilterModel.objects.all()
serializer_class = OrderingFilterSerializer
filter_backends = (filters.OrderingFilter,)
ordering = ('title',)
ordering_fields = ('text',)
@ -497,7 +519,8 @@ class OrderingFilterTests(TestCase):
def test_default_ordering(self):
class OrderingListView(generics.ListAPIView):
model = OrdringFilterModel
queryset = OrdringFilterModel.objects.all()
serializer_class = OrderingFilterSerializer
filter_backends = (filters.OrderingFilter,)
ordering = ('title',)
oredering_fields = ('text',)
@ -516,7 +539,8 @@ class OrderingFilterTests(TestCase):
def test_default_ordering_using_string(self):
class OrderingListView(generics.ListAPIView):
model = OrdringFilterModel
queryset = OrdringFilterModel.objects.all()
serializer_class = OrderingFilterSerializer
filter_backends = (filters.OrderingFilter,)
ordering = 'title'
ordering_fields = ('text',)
@ -545,7 +569,7 @@ class OrderingFilterTests(TestCase):
new_related.save()
class OrderingListView(generics.ListAPIView):
model = OrdringFilterModel
serializer_class = OrderingFilterSerializer
filter_backends = (filters.OrderingFilter,)
ordering = 'title'
ordering_fields = '__all__'
@ -567,7 +591,8 @@ class OrderingFilterTests(TestCase):
def test_ordering_with_nonstandard_ordering_param(self):
with temporary_setting('ORDERING_PARAM', 'order', filters):
class OrderingListView(generics.ListAPIView):
model = OrdringFilterModel
queryset = OrdringFilterModel.objects.all()
serializer_class = OrderingFilterSerializer
filter_backends = (filters.OrderingFilter,)
ordering = ('title',)
ordering_fields = ('text',)

View File

@ -11,18 +11,30 @@ from tests.models import ForeignKeySource, ForeignKeyTarget
factory = APIRequestFactory()
class BasicSerializer(serializers.ModelSerializer):
class Meta:
model = BasicModel
class ForeignKeySerializer(serializers.ModelSerializer):
class Meta:
model = ForeignKeySource
class RootView(generics.ListCreateAPIView):
"""
Example description for OPTIONS.
"""
model = BasicModel
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
class InstanceView(generics.RetrieveUpdateDestroyAPIView):
"""
Example description for OPTIONS.
"""
model = BasicModel
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
def get_queryset(self):
queryset = super(InstanceView, self).get_queryset()
@ -33,7 +45,8 @@ class FKInstanceView(generics.RetrieveUpdateDestroyAPIView):
"""
FK: example description for OPTIONS.
"""
model = ForeignKeySource
queryset = ForeignKeySource.objects.all()
serializer_class = ForeignKeySerializer
class SlugSerializer(serializers.ModelSerializer):
@ -48,7 +61,7 @@ class SlugBasedInstanceView(InstanceView):
"""
A model with a slug-field.
"""
model = SlugBasedModel
queryset = SlugBasedModel.objects.all()
serializer_class = SlugSerializer
lookup_field = 'slug'
@ -503,7 +516,7 @@ class TestOverriddenGetObject(TestCase):
"""
Example detail view for override of get_object().
"""
model = BasicModel
serializer_class = BasicSerializer
def get_object(self):
pk = int(self.kwargs['pk'])
@ -573,7 +586,7 @@ class ClassASerializer(serializers.ModelSerializer):
class ExampleView(generics.ListCreateAPIView):
serializer_class = ClassASerializer
model = ClassA
queryset = ClassA.objects.all()
class TestM2MBrowseableAPI(TestCase):
@ -603,7 +616,7 @@ class TwoFieldModel(models.Model):
class DynamicSerializerView(generics.ListCreateAPIView):
model = TwoFieldModel
queryset = TwoFieldModel.objects.all()
renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer)
def get_serializer_class(self):
@ -612,8 +625,11 @@ class DynamicSerializerView(generics.ListCreateAPIView):
class Meta:
model = TwoFieldModel
fields = ('field_b',)
return DynamicSerializer
return super(DynamicSerializerView, self).get_serializer_class()
else:
class DynamicSerializer(serializers.ModelSerializer):
class Meta:
model = TwoFieldModel
return DynamicSerializer
class TestFilterBackendAppliedToViews(TestCase):

View File

@ -39,59 +39,85 @@ class AlbumSerializer(serializers.ModelSerializer):
fields = ('title', 'url')
class BasicSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = BasicModel
class AnchorSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Anchor
class ManyToManySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ManyToManyModel
class BlogPostSerializer(serializers.ModelSerializer):
class Meta:
model = BlogPost
class OptionalRelationSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = OptionalRelationModel
class BasicList(generics.ListCreateAPIView):
model = BasicModel
model_serializer_class = serializers.HyperlinkedModelSerializer
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
class BasicDetail(generics.RetrieveUpdateDestroyAPIView):
model = BasicModel
model_serializer_class = serializers.HyperlinkedModelSerializer
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
class AnchorDetail(generics.RetrieveAPIView):
model = Anchor
model_serializer_class = serializers.HyperlinkedModelSerializer
queryset = Anchor.objects.all()
serializer_class = AnchorSerializer
class ManyToManyList(generics.ListAPIView):
model = ManyToManyModel
model_serializer_class = serializers.HyperlinkedModelSerializer
queryset = ManyToManyModel.objects.all()
serializer_class = ManyToManySerializer
class ManyToManyDetail(generics.RetrieveAPIView):
model = ManyToManyModel
model_serializer_class = serializers.HyperlinkedModelSerializer
queryset = ManyToManyModel.objects.all()
serializer_class = ManyToManySerializer
class BlogPostCommentListCreate(generics.ListCreateAPIView):
model = BlogPostComment
queryset = BlogPostComment.objects.all()
serializer_class = BlogPostCommentSerializer
class BlogPostCommentDetail(generics.RetrieveAPIView):
model = BlogPostComment
queryset = BlogPostComment.objects.all()
serializer_class = BlogPostCommentSerializer
class BlogPostDetail(generics.RetrieveAPIView):
model = BlogPost
queryset = BlogPost.objects.all()
serializer_class = BlogPostSerializer
class PhotoListCreate(generics.ListCreateAPIView):
model = Photo
model_serializer_class = PhotoSerializer
queryset = Photo.objects.all()
serializer_class = PhotoSerializer
class AlbumDetail(generics.RetrieveAPIView):
model = Album
queryset = Album.objects.all()
serializer_class = AlbumSerializer
lookup_field = 'title'
class OptionalRelationDetail(generics.RetrieveUpdateDestroyAPIView):
model = OptionalRelationModel
model_serializer_class = serializers.HyperlinkedModelSerializer
queryset = OptionalRelationModel.objects.all()
serializer_class = OptionalRelationSerializer
urlpatterns = patterns(

View File

@ -1,10 +1,19 @@
from django.core.urlresolvers import reverse
from django.conf.urls import patterns, url
from rest_framework import serializers, generics
from rest_framework.test import APITestCase
from tests.models import NullableForeignKeySource
from tests.serializers import NullableFKSourceSerializer
from tests.views import NullableFKSourceDetail
class NullableFKSourceSerializer(serializers.ModelSerializer):
class Meta:
model = NullableForeignKeySource
class NullableFKSourceDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = NullableForeignKeySource.objects.all()
serializer_class = NullableFKSourceSerializer
urlpatterns = patterns(

View File

@ -4,7 +4,7 @@ from decimal import Decimal
from django.core.paginator import Paginator
from django.test import TestCase
from django.utils import unittest
from rest_framework import generics, status, pagination, filters, serializers
from rest_framework import generics, serializers, status, pagination, filters
from rest_framework.compat import django_filters
from rest_framework.test import APIRequestFactory
from .models import BasicModel, FilterableItem
@ -22,11 +22,22 @@ def split_arguments_from_url(url):
return path, args
class BasicSerializer(serializers.ModelSerializer):
class Meta:
model = BasicModel
class FilterableItemSerializer(serializers.ModelSerializer):
class Meta:
model = FilterableItem
class RootView(generics.ListCreateAPIView):
"""
Example description for OPTIONS.
"""
model = BasicModel
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
paginate_by = 10
@ -34,14 +45,16 @@ class DefaultPageSizeKwargView(generics.ListAPIView):
"""
View for testing default paginate_by_param usage
"""
model = BasicModel
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
class PaginateByParamView(generics.ListAPIView):
"""
View for testing custom paginate_by_param usage
"""
model = BasicModel
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
paginate_by_param = 'page_size'
@ -49,7 +62,8 @@ class MaxPaginateByView(generics.ListAPIView):
"""
View for testing custom max_paginate_by usage
"""
model = BasicModel
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
paginate_by = 3
max_paginate_by = 5
paginate_by_param = 'page_size'
@ -140,7 +154,8 @@ class IntegrationTestPaginationAndFiltering(TestCase):
fields = ['text', 'decimal', 'date']
class FilterFieldsRootView(generics.ListCreateAPIView):
model = FilterableItem
queryset = FilterableItem.objects.all()
serializer_class = FilterableItemSerializer
paginate_by = 10
filter_class = DecimalFilter
filter_backends = (filters.DjangoFilterBackend,)
@ -188,7 +203,8 @@ class IntegrationTestPaginationAndFiltering(TestCase):
return queryset.filter(decimal__lt=Decimal(request.GET['decimal']))
class BasicFilterFieldsRootView(generics.ListCreateAPIView):
model = FilterableItem
queryset = FilterableItem.objects.all()
serializer_class = FilterableItemSerializer
paginate_by = 10
filter_backends = (DecimalFilterBackend,)
@ -387,7 +403,7 @@ class TestContextPassedToCustomField(TestCase):
def test_with_pagination(self):
class ListView(generics.ListCreateAPIView):
model = BasicModel
queryset = BasicModel.objects.all()
serializer_class = BasicModelSerializer
paginate_by = 1

View File

@ -3,7 +3,7 @@ from django.contrib.auth.models import User, Permission, Group
from django.db import models
from django.test import TestCase
from django.utils import unittest
from rest_framework import generics, status, permissions, authentication, HTTP_HEADER_ENCODING
from rest_framework import generics, serializers, status, permissions, authentication, HTTP_HEADER_ENCODING
from rest_framework.compat import guardian, get_model_name
from rest_framework.filters import DjangoObjectPermissionsFilter
from rest_framework.test import APIRequestFactory
@ -13,14 +13,21 @@ import base64
factory = APIRequestFactory()
class BasicSerializer(serializers.ModelSerializer):
class Meta:
model = BasicModel
class RootView(generics.ListCreateAPIView):
model = BasicModel
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
authentication_classes = [authentication.BasicAuthentication]
permission_classes = [permissions.DjangoModelPermissions]
class InstanceView(generics.RetrieveUpdateDestroyAPIView):
model = BasicModel
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
authentication_classes = [authentication.BasicAuthentication]
permission_classes = [permissions.DjangoModelPermissions]
@ -167,6 +174,11 @@ class BasicPermModel(models.Model):
)
class BasicPermSerializer(serializers.ModelSerializer):
class Meta:
model = BasicPermModel
# Custom object-level permission, that includes 'view' permissions
class ViewObjectPermissions(permissions.DjangoObjectPermissions):
perms_map = {
@ -181,7 +193,8 @@ class ViewObjectPermissions(permissions.DjangoObjectPermissions):
class ObjectPermissionInstanceView(generics.RetrieveUpdateDestroyAPIView):
model = BasicPermModel
queryset = BasicPermModel.objects.all()
serializer_class = BasicPermSerializer
authentication_classes = [authentication.BasicAuthentication]
permission_classes = [ViewObjectPermissions]
@ -189,7 +202,8 @@ object_permissions_view = ObjectPermissionInstanceView.as_view()
class ObjectPermissionListView(generics.ListAPIView):
model = BasicPermModel
queryset = BasicPermModel.objects.all()
serializer_class = BasicPermSerializer
authentication_classes = [authentication.BasicAuthentication]
permission_classes = [ViewObjectPermissions]

View File

@ -86,14 +86,15 @@ class HTMLView1(APIView):
class HTMLNewModelViewSet(viewsets.ModelViewSet):
model = BasicModel
serializer_class = BasicModelSerializer
queryset = BasicModel.objects.all()
class HTMLNewModelView(generics.ListCreateAPIView):
renderer_classes = (BrowsableAPIRenderer,)
permission_classes = []
serializer_class = BasicModelSerializer
model = BasicModel
queryset = BasicModel.objects.all()
new_model_viewset_router = routers.DefaultRouter()

View File

@ -22,7 +22,7 @@ class ValidationModelSerializer(serializers.ModelSerializer):
class UpdateValidationModel(generics.RetrieveUpdateDestroyAPIView):
model = ValidationModel
queryset = ValidationModel.objects.all()
serializer_class = ValidationModelSerializer
@ -117,7 +117,7 @@ class ValidationMaxValueValidatorModelSerializer(serializers.ModelSerializer):
class UpdateMaxValueValidationModel(generics.RetrieveUpdateDestroyAPIView):
model = ValidationMaxValueValidatorModel
queryset = ValidationMaxValueValidatorModel.objects.all()
serializer_class = ValidationMaxValueValidatorModelSerializer

View File

@ -1,8 +0,0 @@
from rest_framework import generics
from .models import NullableForeignKeySource
from .serializers import NullableFKSourceSerializer
class NullableFKSourceDetail(generics.RetrieveUpdateDestroyAPIView):
model = NullableForeignKeySource
model_serializer_class = NullableFKSourceSerializer