mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-10 19:56:59 +03:00
Drop out attribute
This commit is contained in:
parent
81c3b4f250
commit
21ae3a6691
|
@ -374,16 +374,20 @@ Returns the field instance that should be used to represent the pk field.
|
|||
|
||||
### get_nested_field
|
||||
|
||||
**Signature**: `.get_nested_field(self, model_field)`
|
||||
**Signature**: `.get_nested_field(self, model_field, related_model, to_many)`
|
||||
|
||||
Returns the field instance that should be used to represent a related field when `depth` is specified as being non-zero.
|
||||
|
||||
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.
|
||||
|
||||
### get_related_field
|
||||
|
||||
**Signature**: `.get_related_field(self, model_field, to_many=False)`
|
||||
**Signature**: `.get_related_field(self, model_field, related_model, to_many)`
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
### get_field
|
||||
|
||||
**Signature**: `.get_field(self, model_field)`
|
||||
|
|
|
@ -79,34 +79,26 @@ 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:
|
||||
Here's our project's root `urls.py` module:
|
||||
|
||||
from django.conf.urls.defaults import url, patterns, include
|
||||
from django.contrib.auth.models import User, Group
|
||||
from rest_framework import viewsets, routers
|
||||
|
||||
|
||||
# ViewSets define the view behavior.
|
||||
class UserViewSet(viewsets.ModelViewSet):
|
||||
queryset = User.objects.all()
|
||||
fields = ('url', 'email', 'is_staff', 'groups')
|
||||
|
||||
model = User
|
||||
|
||||
class GroupViewSet(viewsets.ModelViewSet):
|
||||
queryset = Group.objects.all()
|
||||
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
|
||||
|
||||
model = Group
|
||||
|
||||
|
||||
# Routers provide an easy way of automatically determining the URL conf
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r'users', views.UserViewSet, name='user')
|
||||
router.register(r'groups', views.GroupViewSet, name='group')
|
||||
|
||||
|
||||
# Wire up our API using automatic URL routing.
|
||||
# Additionally, we include login URLs for the browseable API.
|
||||
urlpatterns = patterns('',
|
||||
|
|
|
@ -4,7 +4,6 @@ REST framework 2.3 is geared towards making it easier and quicker to build your
|
|||
|
||||
## ViewSets & Routers
|
||||
|
||||
**TODO**
|
||||
|
||||
## Easier Serializers
|
||||
|
||||
|
@ -132,13 +131,21 @@ If you've been customizing this behavior, for example perhaps to use `rst` marku
|
|||
|
||||
Note that the relevant methods have always been private APIs, and the docstrings called them out as intended to be deprecated.
|
||||
|
||||
## ModelSerializers and reverse relationships
|
||||
|
||||
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.
|
||||
|
||||
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`.
|
||||
|
||||
The old-style signature will continue to function but will raise a `PendingDeprecationWarning`.
|
||||
|
||||
---
|
||||
|
||||
# Other notes
|
||||
|
||||
## Explict view attributes
|
||||
## More explicit style
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
For example, the following is now the recommended style for using generic views:
|
||||
|
||||
|
@ -146,9 +153,9 @@ For example, the following is now the recommended style for using generic views:
|
|||
queryset = MyModel.objects.all()
|
||||
serializer_class = MyModelSerializer
|
||||
|
||||
Using an explict `queryset` attribute makes the functioning of the view more clear than using the shortcut `model` attribute.
|
||||
Using an explict `queryset` and `serializer_class` attributes makes the functioning of the view more clear than using the shortcut `model` attribute.
|
||||
|
||||
It also makes the usage of an overridden `get_queryset()` method more obvious.
|
||||
It also makes the usage of the `get_queryset()` or `get_serializer_class()` methods more obvious.
|
||||
|
||||
class AccountListView(generics.RetrieveAPIView):
|
||||
serializer_class = MyModelSerializer
|
||||
|
@ -167,6 +174,10 @@ It also makes the usage of an overridden `get_queryset()` method more obvious.
|
|||
|
||||
The 2.3 release series will be the last series to provide compatiblity with Django 1.3.
|
||||
|
||||
## Version 2.2 API changes
|
||||
|
||||
All API changes in 2.2 that previously raised `PendingDeprecationWarning` will now raise a `DeprecationWarning`, which is loud by default.
|
||||
|
||||
## What comes next?
|
||||
|
||||
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.
|
||||
|
|
|
@ -20,11 +20,17 @@ class GenericAPIView(views.APIView):
|
|||
"""
|
||||
|
||||
# You'll need to either set these attributes,
|
||||
# or override `get_queryset`/`get_serializer_class`.
|
||||
# or override `get_queryset()`/`get_serializer_class()`.
|
||||
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'
|
||||
|
||||
# Pagination settings
|
||||
|
@ -39,15 +45,6 @@ class GenericAPIView(views.APIView):
|
|||
# Determines if the view will return 200 or 404 responses for empty lists.
|
||||
allow_empty = True
|
||||
|
||||
# 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
|
||||
|
||||
# This shortcut may be used instead of setting the `serializer_class`
|
||||
# attribute, although using the explicit style is generally preferred.
|
||||
fields = None
|
||||
|
||||
# The following attributes may be subject to change,
|
||||
# and should be considered private API.
|
||||
model_serializer_class = api_settings.DEFAULT_MODEL_SERIALIZER_CLASS
|
||||
|
@ -193,16 +190,15 @@ class GenericAPIView(views.APIView):
|
|||
if serializer_class is not None:
|
||||
return serializer_class
|
||||
|
||||
assert self.model is not None or self.queryset is not None, \
|
||||
assert self.model is not None, \
|
||||
"'%s' should either include a 'serializer_class' attribute, " \
|
||||
"or use the 'queryset' or 'model' attribute as a shortcut for " \
|
||||
"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 or self.queryset.model
|
||||
fields = self.fields
|
||||
model = self.model
|
||||
return DefaultSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
|
|
|
@ -677,6 +677,8 @@ class ModelSerializer(Serializer):
|
|||
def get_nested_field(self, model_field, related_model, to_many):
|
||||
"""
|
||||
Creates a default instance of a nested relational field.
|
||||
|
||||
Note that model_field will be `None` for reverse relationships.
|
||||
"""
|
||||
class NestedModelSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
|
@ -686,6 +688,8 @@ class ModelSerializer(Serializer):
|
|||
def get_related_field(self, model_field, related_model, to_many):
|
||||
"""
|
||||
Creates a default instance of a flat relational field.
|
||||
|
||||
Note that model_field will be `None` for reverse relationships.
|
||||
"""
|
||||
# TODO: filter queryset using:
|
||||
# .using(db).complex_filter(self.rel.limit_choices_to)
|
||||
|
|
|
@ -344,32 +344,6 @@ 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):
|
||||
queryset = BasicModel.objects.all()
|
||||
fields = ('text',)
|
||||
|
||||
class RegularView(generics.RetrieveUpdateDestroyAPIView):
|
||||
queryset = BasicModel.objects.all()
|
||||
|
||||
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'])
|
||||
self.assertEqual(Serializer().opts.model, BasicModel)
|
||||
|
||||
def test_not_overridden_fields_view(self):
|
||||
Serializer = self.regular_view.get_serializer_class()
|
||||
self.assertEqual(Serializer().fields.keys(), ['id', 'text'])
|
||||
self.assertEqual(Serializer().opts.model, BasicModel)
|
||||
|
||||
|
||||
# Regression test for #285
|
||||
|
||||
class CommentSerializer(serializers.ModelSerializer):
|
||||
|
|
Loading…
Reference in New Issue
Block a user