mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-03 20:10:10 +03:00
Merge 2baf04dee2
into add1260be4
This commit is contained in:
commit
d0b3bb4d6a
|
@ -64,7 +64,8 @@ Each of the concrete generic views provided is built by combining `GenericAPIVie
|
|||
The following attributes control the basic view behavior.
|
||||
|
||||
* `queryset` - The queryset that should be used for returning objects from this view. Typically, you must either set this attribute, or override the `get_queryset()` method.
|
||||
* `serializer_class` - The serializer class that should be used for validating and deserializing input, and for serializing output. Typically, you must either set this attribute, or override the `get_serializer_class()` method.
|
||||
* `serializer_class` - The serializer class that should be used for validating and deserializing input. Typically, you must either set this attribute, or override the `get_serializer_class()` method.
|
||||
* `serializer_class_for_output` - The serializer class that should be used for deserializing input, and for serializing output. You don't have to set this, if it is unset, `serializer_class` is used instead by default. You can override `get_serializer_class_for_output()` to change this behavior.
|
||||
* `lookup_field` - The model field that should be used to for performing object lookup of individual model instances. Defaults to `'pk'`. Note that when using hyperlinked APIs you'll need to ensure that *both* the API views *and* the serializer classes set the lookup fields if you need to use a custom value.
|
||||
* `lookup_url_kwarg` - The URL keyword argument that should be used for object lookup. The URL conf should include a keyword argument corresponding to this value. If unset this defaults to using the same value as `lookup_field`.
|
||||
|
||||
|
@ -141,7 +142,7 @@ For example:
|
|||
|
||||
Returns the class that should be used for the serializer. Defaults to returning the `serializer_class` attribute, or dynamically generating a serializer class if the `model` shortcut is being used.
|
||||
|
||||
May be override to provide dynamic behavior such as using different serializers for read and write operations, or providing different serializers to different types of users.
|
||||
May be override to provide dynamic behavior such as providing different serializers to different types of users. To usie different serializers for read and write operations, see `get_serializer_class_for_output`.
|
||||
|
||||
For example:
|
||||
|
||||
|
@ -150,6 +151,36 @@ For example:
|
|||
return FullAccountSerializer
|
||||
return BasicAccountSerializer
|
||||
|
||||
#### `get_serializer_class_for_output(self)`
|
||||
|
||||
Returns the class that should be used for the serializer when deserializing objects. By default this returns the `serializer_class_for_output` attribute. If this attribute is not set, this is identical to `get_serializer_class`.
|
||||
|
||||
This method allows you to use a different serializer for read and write operations on objects. For example:
|
||||
|
||||
class Album(Model):
|
||||
title = CharField(max_length=127)
|
||||
|
||||
class Track(Model):
|
||||
title = CharField(max_length=127)
|
||||
album = ForeignKey(Album, related_name='tracks')
|
||||
|
||||
class TrackSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
fields = ('title', 'album')
|
||||
|
||||
class TrackSerializerWithDetails(ModelSerializer):
|
||||
album = AlbumSerializer()
|
||||
|
||||
class Meta:
|
||||
fields = ('title', 'album')
|
||||
|
||||
In this situation you may wish to display the full album information in the Track view, but you want the album field to be editable, and you don't want to supply a full Album object when updating or creating a Track. This is easily done by creating your ModelViewSet as such:
|
||||
|
||||
class TrackViewSet(ModelViewSet):
|
||||
queryset = Track.objects.all()
|
||||
serializer_class = TrackSerializer
|
||||
serializer_class_for_output = TrackSerializerWithDetails
|
||||
|
||||
#### `get_paginate_by(self)`
|
||||
|
||||
Returns the page size to use with pagination. By default this uses the `paginate_by` attribute, and may be overridden by the client if the `paginate_by_param` attribute is set.
|
||||
|
|
|
@ -46,6 +46,11 @@ class GenericAPIView(views.APIView):
|
|||
queryset = None
|
||||
serializer_class = None
|
||||
|
||||
# You may set this attribute to use a different serializer for
|
||||
# deserializing objects. You can override
|
||||
# `get_serializer_class_for_output()` instead of setting it.
|
||||
serializer_class_for_output = 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.
|
||||
|
@ -94,7 +99,7 @@ class GenericAPIView(views.APIView):
|
|||
partial=False, allow_add_remove=False):
|
||||
"""
|
||||
Return the serializer instance that should be used for validating and
|
||||
deserializing input, and for serializing output.
|
||||
deserializing input.
|
||||
"""
|
||||
serializer_class = self.get_serializer_class()
|
||||
context = self.get_serializer_context()
|
||||
|
@ -103,13 +108,23 @@ class GenericAPIView(views.APIView):
|
|||
allow_add_remove=allow_add_remove,
|
||||
context=context)
|
||||
|
||||
def get_serializer_for_output(self, instance=None, many=False):
|
||||
"""
|
||||
Return the serializer instance that should be used for
|
||||
serializing output. Defaults to the serializer instance used
|
||||
for deserializing input.
|
||||
"""
|
||||
serializer_class = self.get_serializer_class_for_output()
|
||||
context = self.get_serializer_context()
|
||||
return serializer_class(instance, context=context, many=many)
|
||||
|
||||
def get_pagination_serializer(self, page):
|
||||
"""
|
||||
Return a serializer instance to use with paginated data.
|
||||
"""
|
||||
class SerializerClass(self.pagination_serializer_class):
|
||||
class Meta:
|
||||
object_serializer_class = self.get_serializer_class()
|
||||
object_serializer_class = self.get_serializer_class_for_output()
|
||||
|
||||
pagination_serializer_class = SerializerClass
|
||||
context = self.get_serializer_context()
|
||||
|
@ -252,6 +267,19 @@ class GenericAPIView(views.APIView):
|
|||
model = self.model
|
||||
return DefaultSerializer
|
||||
|
||||
def get_serializer_class_for_output(self):
|
||||
"""
|
||||
Return the class to use for the serializer when deserializing
|
||||
objects.
|
||||
|
||||
Defaults to using `self.serializer_class_for_output`, if None,
|
||||
defaults to `self.get_serializer()`.
|
||||
"""
|
||||
serializer_class = self.serializer_class_for_output
|
||||
if serializer_class is None:
|
||||
return self.get_serializer_class()
|
||||
return serializer_class
|
||||
|
||||
def get_queryset(self):
|
||||
"""
|
||||
Get the list of items for this view.
|
||||
|
|
|
@ -53,8 +53,9 @@ class CreateModelMixin(object):
|
|||
self.pre_save(serializer.object)
|
||||
self.object = serializer.save(force_insert=True)
|
||||
self.post_save(self.object, created=True)
|
||||
out_serializer = self.get_serializer_for_output(self.object)
|
||||
headers = self.get_success_headers(serializer.data)
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED,
|
||||
return Response(out_serializer.data, status=status.HTTP_201_CREATED,
|
||||
headers=headers)
|
||||
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
@ -93,7 +94,8 @@ class ListModelMixin(object):
|
|||
if page is not None:
|
||||
serializer = self.get_pagination_serializer(page)
|
||||
else:
|
||||
serializer = self.get_serializer(self.object_list, many=True)
|
||||
serializer = self.get_serializer_for_output(
|
||||
self.object_list, many=True)
|
||||
|
||||
return Response(serializer.data)
|
||||
|
||||
|
@ -104,7 +106,7 @@ class RetrieveModelMixin(object):
|
|||
"""
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
serializer = self.get_serializer(self.object)
|
||||
serializer = self.get_serializer_for_output(self.object)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
|
@ -136,7 +138,8 @@ class UpdateModelMixin(object):
|
|||
|
||||
self.object = serializer.save(force_update=True)
|
||||
self.post_save(self.object, created=False)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
out_serializer = self.get_serializer_for_output(self.object)
|
||||
return Response(out_serializer.data, status=status.HTTP_200_OK)
|
||||
|
||||
def partial_update(self, request, *args, **kwargs):
|
||||
kwargs['partial'] = True
|
||||
|
|
Loading…
Reference in New Issue
Block a user