Skip to content

Commit 21ae3a6

Browse files
Drop out attribute
1 parent 81c3b4f commit 21ae3a6

File tree

6 files changed

+42
-61
lines changed

6 files changed

+42
-61
lines changed

docs/api-guide/serializers.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,16 +374,20 @@ Returns the field instance that should be used to represent the pk field.
374374

375375
### get_nested_field
376376

377-
**Signature**: `.get_nested_field(self, model_field)`
377+
**Signature**: `.get_nested_field(self, model_field, related_model, to_many)`
378378

379379
Returns the field instance that should be used to represent a related field when `depth` is specified as being non-zero.
380380

381+
Note that the `model_field` argument will be `None` for reverse relationships. The `related_model` argument will be the model class for the target of the field. The `to_many` argument will be a boolean indicating if this is a to-one or to-many relationship.
382+
381383
### get_related_field
382384

383-
**Signature**: `.get_related_field(self, model_field, to_many=False)`
385+
**Signature**: `.get_related_field(self, model_field, related_model, to_many)`
384386

385387
Returns the field instance that should be used to represent a related field when `depth` is not specified, or when nested representations are being used and the depth reaches zero.
386388

389+
Note that the `model_field` argument will be `None` for reverse relationships. The `related_model` argument will be the model class for the target of the field. The `to_many` argument will be a boolean indicating if this is a to-one or to-many relationship.
390+
387391
### get_field
388392

389393
**Signature**: `.get_field(self, model_field)`

docs/index.md

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,34 +79,26 @@ Let's take a look at a quick example of using REST framework to build a simple m
7979

8080
We'll create a read-write API for accessing users and groups.
8181

82-
Here's our `views.py` module:
82+
Here's our project's root `urls.py` module:
8383

8484
from django.conf.urls.defaults import url, patterns, include
8585
from django.contrib.auth.models import User, Group
8686
from rest_framework import viewsets, routers
8787

88-
8988
# ViewSets define the view behavior.
9089
class UserViewSet(viewsets.ModelViewSet):
91-
queryset = User.objects.all()
92-
fields = ('url', 'email', 'is_staff', 'groups')
93-
90+
model = User
9491

9592
class GroupViewSet(viewsets.ModelViewSet):
96-
queryset = Group.objects.all()
97-
fields = ('url', 'name')
98-
99-
And our `urls.py` setup:
100-
101-
from django.conf.urls.defaults import url, patterns, include
102-
from myapp import views
103-
from rest_framework import routers
104-
93+
model = Group
10594

95+
96+
# Routers provide an easy way of automatically determining the URL conf
10697
router = routers.DefaultRouter()
10798
router.register(r'users', views.UserViewSet, name='user')
10899
router.register(r'groups', views.GroupViewSet, name='group')
109100

101+
110102
# Wire up our API using automatic URL routing.
111103
# Additionally, we include login URLs for the browseable API.
112104
urlpatterns = patterns('',

docs/topics/2.3-announcement.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ REST framework 2.3 is geared towards making it easier and quicker to build your
44

55
## ViewSets & Routers
66

7-
**TODO**
87

98
## Easier Serializers
109

@@ -132,23 +131,31 @@ If you've been customizing this behavior, for example perhaps to use `rst` marku
132131

133132
Note that the relevant methods have always been private APIs, and the docstrings called them out as intended to be deprecated.
134133

134+
## ModelSerializers and reverse relationships
135+
136+
The support for adding reverse relationships to the `fields` option on a `ModelSerializer` class means that the `get_related_field` and `get_nested_field` method signatures have now changed.
137+
138+
In the unlikely event that you're providing a custom serializer class, and implementing these methods you should note the new call signature for both methods is now `(self, model_field, related_model, to_many)`. For revese relationships `model_field` will be `None`.
139+
140+
The old-style signature will continue to function but will raise a `PendingDeprecationWarning`.
141+
135142
---
136143

137144
# Other notes
138145

139-
## Explict view attributes
146+
## More explicit style
140147

141-
The usage of `model` attribute in generic Views is still supported, but it's usage is being discouraged in favour of the more explict `queryset` attribute.
148+
The usage of `model` attribute in generic Views is still supported, but it's usage is being discouraged in favour of the setting the mode explict `queryset` and `serializer_class` attributes.
142149

143150
For example, the following is now the recommended style for using generic views:
144151

145152
class AccountListView(generics.RetrieveAPIView):
146153
queryset = MyModel.objects.all()
147154
serializer_class = MyModelSerializer
148155

149-
Using an explict `queryset` attribute makes the functioning of the view more clear than using the shortcut `model` attribute.
156+
Using an explict `queryset` and `serializer_class` attributes makes the functioning of the view more clear than using the shortcut `model` attribute.
150157

151-
It also makes the usage of an overridden `get_queryset()` method more obvious.
158+
It also makes the usage of the `get_queryset()` or `get_serializer_class()` methods more obvious.
152159

153160
class AccountListView(generics.RetrieveAPIView):
154161
serializer_class = MyModelSerializer
@@ -167,6 +174,10 @@ It also makes the usage of an overridden `get_queryset()` method more obvious.
167174

168175
The 2.3 release series will be the last series to provide compatiblity with Django 1.3.
169176

177+
## Version 2.2 API changes
178+
179+
All API changes in 2.2 that previously raised `PendingDeprecationWarning` will now raise a `DeprecationWarning`, which is loud by default.
180+
170181
## What comes next?
171182

172183
The plan for the next few months is to concentrate on addressing outstanding tickets. 2.4 is likely to deal with relatively small refinements to the existing API.

rest_framework/generics.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,17 @@ class GenericAPIView(views.APIView):
2020
"""
2121

2222
# You'll need to either set these attributes,
23-
# or override `get_queryset`/`get_serializer_class`.
23+
# or override `get_queryset()`/`get_serializer_class()`.
2424
queryset = None
2525
serializer_class = None
2626

27+
# This shortcut may be used instead of setting either or both
28+
# of the `queryset`/`serializer_class` attributes, although using
29+
# the explicit style is generally preferred.
30+
model = None
31+
2732
# If you want to use object lookups other than pk, set this attribute.
33+
# For more complex lookup requirements override `get_object()`.
2834
lookup_field = 'pk'
2935

3036
# Pagination settings
@@ -39,15 +45,6 @@ class GenericAPIView(views.APIView):
3945
# Determines if the view will return 200 or 404 responses for empty lists.
4046
allow_empty = True
4147

42-
# This shortcut may be used instead of setting either (or both)
43-
# of the `queryset`/`serializer_class` attributes, although using
44-
# the explicit style is generally preferred.
45-
model = None
46-
47-
# This shortcut may be used instead of setting the `serializer_class`
48-
# attribute, although using the explicit style is generally preferred.
49-
fields = None
50-
5148
# The following attributes may be subject to change,
5249
# and should be considered private API.
5350
model_serializer_class = api_settings.DEFAULT_MODEL_SERIALIZER_CLASS
@@ -193,16 +190,15 @@ def get_serializer_class(self):
193190
if serializer_class is not None:
194191
return serializer_class
195192

196-
assert self.model is not None or self.queryset is not None, \
193+
assert self.model is not None, \
197194
"'%s' should either include a 'serializer_class' attribute, " \
198-
"or use the 'queryset' or 'model' attribute as a shortcut for " \
195+
"or use the 'model' attribute as a shortcut for " \
199196
"automatically generating a serializer class." \
200197
% self.__class__.__name__
201198

202199
class DefaultSerializer(self.model_serializer_class):
203200
class Meta:
204-
model = self.model or self.queryset.model
205-
fields = self.fields
201+
model = self.model
206202
return DefaultSerializer
207203

208204
def get_queryset(self):

rest_framework/serializers.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,8 @@ def get_pk_field(self, model_field):
677677
def get_nested_field(self, model_field, related_model, to_many):
678678
"""
679679
Creates a default instance of a nested relational field.
680+
681+
Note that model_field will be `None` for reverse relationships.
680682
"""
681683
class NestedModelSerializer(ModelSerializer):
682684
class Meta:
@@ -686,6 +688,8 @@ class Meta:
686688
def get_related_field(self, model_field, related_model, to_many):
687689
"""
688690
Creates a default instance of a flat relational field.
691+
692+
Note that model_field will be `None` for reverse relationships.
689693
"""
690694
# TODO: filter queryset using:
691695
# .using(db).complex_filter(self.rel.limit_choices_to)

rest_framework/tests/generics.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -344,32 +344,6 @@ def test_overridden_get_object_view(self):
344344
self.assertEqual(response.data, self.data[0])
345345

346346

347-
class TestFieldsShortcut(TestCase):
348-
"""
349-
Test cases for setting the `fields` attribute on a view.
350-
"""
351-
def setUp(self):
352-
class OverriddenFieldsView(generics.RetrieveUpdateDestroyAPIView):
353-
queryset = BasicModel.objects.all()
354-
fields = ('text',)
355-
356-
class RegularView(generics.RetrieveUpdateDestroyAPIView):
357-
queryset = BasicModel.objects.all()
358-
359-
self.overridden_fields_view = OverriddenFieldsView()
360-
self.regular_view = RegularView()
361-
362-
def test_overridden_fields_view(self):
363-
Serializer = self.overridden_fields_view.get_serializer_class()
364-
self.assertEqual(Serializer().fields.keys(), ['text'])
365-
self.assertEqual(Serializer().opts.model, BasicModel)
366-
367-
def test_not_overridden_fields_view(self):
368-
Serializer = self.regular_view.get_serializer_class()
369-
self.assertEqual(Serializer().fields.keys(), ['id', 'text'])
370-
self.assertEqual(Serializer().opts.model, BasicModel)
371-
372-
373347
# Regression test for #285
374348

375349
class CommentSerializer(serializers.ModelSerializer):

0 commit comments

Comments
 (0)