diff --git a/docs/index.md b/docs/index.md index e2dd9fbae..931d6114f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -79,42 +79,35 @@ Let's take a look at a quick example of using REST framework to build a simple m We'll create a read-write API for accessing users and groups. +Here's our `views.py` module: + from django.conf.urls.defaults import url, patterns, include from django.contrib.auth.models import User, Group - from rest_framework import serializers, viewsets, routers - - - # Serializers control the representations your API exposes. - class UserSerializer(serializers.HyperlinkedModelSerializer): - class Meta: - model = User - fields = ('url', 'email', 'is_staff', 'groups') - - - class GroupSerializer(serializers.HyperlinkedModelSerializer): - class Meta: - model = Group - fields = ('url', 'name') + from rest_framework import viewsets, routers # ViewSets define the view behavior. class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() - serializer_class = UserSerializer + fields = ('url', 'email', 'is_staff', 'groups') class GroupViewSet(viewsets.ModelViewSet): queryset = Group.objects.all() - serializer_class = GroupSerializer + fields = ('url', 'name') + +And our `urls.py` setup: + + from django.conf.urls.defaults import url, patterns, include + from myapp import views + from rest_framework import routers - # Routers provide a convienient way of automatically managing your URLs. router = routers.DefaultRouter() - router.register(r'users', UserViewSet, 'user') - router.register(r'groups', GroupViewSet, 'group') + router.register(r'users', views.UserViewSet, name='user') + router.register(r'groups', views.GroupViewSet, name='group') - - # Wire up our API URLs, letting the router do the hard work. + # Wire up our API using automatic URL routing. # Additionally, we include login URLs for the browseable API. urlpatterns = patterns('', url(r'^', include(router.urls)), diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 972424e63..0b8e4a157 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -44,6 +44,10 @@ class GenericAPIView(views.APIView): # the explicit style is generally preferred. model = None + # This shortcut may be used instead of setting the `serializer_class` + # attribute, although using the explicit style is generally preferred. + fields = None + # If the `model` shortcut is used instead of `serializer_class`, then the # serializer class will be constructed using this class as the base. model_serializer_class = api_settings.DEFAULT_MODEL_SERIALIZER_CLASS @@ -193,6 +197,7 @@ class GenericAPIView(views.APIView): class DefaultSerializer(self.model_serializer_class): class Meta: model = self.model + fields = self.fields return DefaultSerializer def get_queryset(self): diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 3afb74757..f4a200973 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -645,7 +645,7 @@ class ModelSerializer(Serializer): for relation in reverse_rels: accessor_name = relation.get_accessor_name() - if accessor_name not in self.opts.fields: + if not self.opts.fields or accessor_name not in self.opts.fields: continue related_model = relation.model to_many = relation.field.rel.multiple diff --git a/rest_framework/tests/generics.py b/rest_framework/tests/generics.py index 4a13389a0..12c9b6778 100644 --- a/rest_framework/tests/generics.py +++ b/rest_framework/tests/generics.py @@ -344,6 +344,30 @@ class TestOverriddenGetObject(TestCase): self.assertEqual(response.data, self.data[0]) +class TestFieldsShortcut(TestCase): + """ + Test cases for setting the `fields` attribute on a view. + """ + def setUp(self): + class OverriddenFieldsView(generics.RetrieveUpdateDestroyAPIView): + model = BasicModel + fields = ('text',) + + class RegularView(generics.RetrieveUpdateDestroyAPIView): + model = BasicModel + + self.overridden_fields_view = OverriddenFieldsView() + self.regular_view = RegularView() + + def test_overridden_fields_view(self): + Serializer = self.overridden_fields_view.get_serializer_class() + self.assertEqual(Serializer().fields.keys(), ['text']) + + def test_not_overridden_fields_view(self): + Serializer = self.regular_view.get_serializer_class() + self.assertEqual(Serializer().fields.keys(), ['id', 'text']) + + # Regression test for #285 class CommentSerializer(serializers.ModelSerializer):