mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-24 08:14:16 +03:00
First pass at mixins & generic views
This commit is contained in:
parent
a092a72844
commit
6e21915934
|
@ -0,0 +1,64 @@
|
|||
from djangorestframework import status
|
||||
from djangorestframework.response import Response
|
||||
|
||||
|
||||
class CreateModelMixin(object):
|
||||
"""
|
||||
Create a model instance.
|
||||
Should be mixed in with any `APIView`
|
||||
"""
|
||||
def create(self, request, *args, **kwargs):
|
||||
serializer = self.get_serializer(data=request.DATA)
|
||||
if serializer.is_valid():
|
||||
self.object = serializer.object
|
||||
self.object.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.error_data, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
class ListModelMixin(object):
|
||||
"""
|
||||
List a queryset.
|
||||
Should be mixed in with `MultipleObjectBaseView`.
|
||||
"""
|
||||
def list(self, request, *args, **kwargs):
|
||||
self.object_list = self.get_queryset()
|
||||
serializer = self.get_serializer(instance=self.object_list)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
class RetrieveModelMixin(object):
|
||||
"""
|
||||
Retrieve a model instance.
|
||||
Should be mixed in with `SingleObjectBaseView`.
|
||||
"""
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
serializer = self.get_serializer(instance=self.object)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
class UpdateModelMixin(object):
|
||||
"""
|
||||
Update a model instance.
|
||||
Should be mixed in with `SingleObjectBaseView`.
|
||||
"""
|
||||
def update(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
serializer = self.get_serializer(data=request.DATA, instance=self.object)
|
||||
if serializer.is_valid():
|
||||
self.object = serializer.deserialized
|
||||
self.object.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.error_data, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
class DestroyModelMixin(object):
|
||||
"""
|
||||
Destroy a model instance.
|
||||
Should be mixed in with `SingleObjectBaseView`.
|
||||
"""
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
self.object.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
|
@ -11,12 +11,14 @@ from django.http import Http404
|
|||
from django.utils.html import escape
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
from django.views.generic.list import MultipleObjectMixin
|
||||
|
||||
from djangorestframework.compat import View as _View, apply_markdown
|
||||
from djangorestframework.response import Response
|
||||
from djangorestframework.request import Request
|
||||
from djangorestframework.settings import api_settings
|
||||
from djangorestframework import parsers, authentication, permissions, status, exceptions
|
||||
from djangorestframework import parsers, authentication, permissions, status, exceptions, mixins
|
||||
|
||||
|
||||
__all__ = (
|
||||
|
@ -281,3 +283,71 @@ class APIView(_View):
|
|||
field_name_types[name] = field.__class__.__name__
|
||||
content['fields'] = field_name_types
|
||||
raise Response(content, status=status.HTTP_200_OK)
|
||||
|
||||
# TODO: .get_serializer()
|
||||
|
||||
|
||||
### Abstract view classes, that do not provide any method handlers ###
|
||||
|
||||
class MultipleObjectBaseView(MultipleObjectMixin, APIView):
|
||||
"""
|
||||
Base class for views onto a queryset.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class SingleObjectBaseView(SingleObjectMixin, APIView):
|
||||
"""
|
||||
Base class for views onto a model instance.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
### Concrete view classes, that provide existing method handlers ###
|
||||
|
||||
class ListAPIView(mixins.ListModelMixin,
|
||||
MultipleObjectBaseView):
|
||||
"""
|
||||
Concrete view for listing a queryset.
|
||||
"""
|
||||
def get(self, request, *args, **kwargs):
|
||||
return self.list(request, *args, **kwargs)
|
||||
|
||||
|
||||
class RootAPIView(mixins.ListModelMixin,
|
||||
mixins.CreateModelMixin,
|
||||
MultipleObjectBaseView):
|
||||
"""
|
||||
Concrete view for listing a queryset or creating a model instance.
|
||||
"""
|
||||
def get(self, request, *args, **kwargs):
|
||||
return self.list(request, *args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
return self.create(request, *args, **kwargs)
|
||||
|
||||
|
||||
class DetailAPIView(mixins.RetrieveModelMixin,
|
||||
SingleObjectBaseView):
|
||||
"""
|
||||
Concrete view for retrieving a model instance.
|
||||
"""
|
||||
def get(self, request, *args, **kwargs):
|
||||
return self.retrieve(request, *args, **kwargs)
|
||||
|
||||
|
||||
class InstanceAPIView(mixins.RetrieveModelMixin,
|
||||
mixins.UpdateModelMixin,
|
||||
mixins.DestroyModelMixin,
|
||||
SingleObjectBaseView):
|
||||
"""
|
||||
Concrete view for retrieving, updating or deleting a model instance.
|
||||
"""
|
||||
def get(self, request, *args, **kwargs):
|
||||
return self.retrieve(request, *args, **kwargs)
|
||||
|
||||
def put(self, request, *args, **kwargs):
|
||||
return self.update(request, *args, **kwargs)
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
return self.destroy(request, *args, **kwargs)
|
||||
|
|
|
@ -57,7 +57,7 @@ So far, so good. It looks pretty similar to the previous case, but we've got be
|
|||
comment = serializer.deserialized
|
||||
comment.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response(serializer.error_data, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def delete(self, request, pk, format=None):
|
||||
comment = self.get_object(pk)
|
||||
|
@ -79,27 +79,38 @@ We can compose those mixin classes, to recreate our existing API behaviour with
|
|||
|
||||
from blog.models import Comment
|
||||
from blog.serializers import CommentSerializer
|
||||
from djangorestframework import mixins, views
|
||||
from djangorestframework import mixins
|
||||
from djangorestframework import views
|
||||
|
||||
class CommentRoot(mixins.ListModelQuerysetMixin,
|
||||
mixins.CreateModelInstanceMixin,
|
||||
views.BaseRootAPIView):
|
||||
|
||||
class CommentRoot(mixins.ListModelMixin,
|
||||
mixins.CreateModelMixin,
|
||||
views.MultipleObjectBaseView):
|
||||
model = Comment
|
||||
serializer_class = CommentSerializer
|
||||
|
||||
get = list
|
||||
post = create
|
||||
def get(self, request, *args, **kwargs):
|
||||
return self.list(request, *args, **kwargs)
|
||||
|
||||
class CommentInstance(mixins.RetrieveModelInstanceMixin,
|
||||
mixins.UpdateModelInstanceMixin,
|
||||
mixins.DestroyModelInstanceMixin,
|
||||
views.BaseInstanceAPIView):
|
||||
def post(self, request, *args, **kwargs):
|
||||
return self.create(request, *args, **kwargs)
|
||||
|
||||
|
||||
class CommentInstance(mixins.RetrieveModelMixin,
|
||||
mixins.UpdateModelMixin,
|
||||
mixins.DestroyModelMixin,
|
||||
views.SingleObjectBaseView):
|
||||
model = Comment
|
||||
serializer_class = CommentSerializer
|
||||
|
||||
get = retrieve
|
||||
put = update
|
||||
delete = destroy
|
||||
def get(self, request, *args, **kwargs):
|
||||
return self.retrieve(request, *args, **kwargs)
|
||||
|
||||
def put(self, request, *args, **kwargs):
|
||||
return self.update(request, *args, **kwargs)
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
return self.destroy(request, *args, **kwargs)
|
||||
|
||||
## Reusing generic class based views
|
||||
|
||||
|
@ -109,11 +120,11 @@ That's a lot less code than before, but we can go one step further still. REST
|
|||
from blog.serializers import CommentSerializer
|
||||
from djangorestframework import views
|
||||
|
||||
class CommentRoot(views.RootAPIView):
|
||||
class CommentRoot(views.RootModelView):
|
||||
model = Comment
|
||||
serializer_class = CommentSerializer
|
||||
|
||||
class CommentInstance(views.InstanceAPIView):
|
||||
class CommentInstance(views.InstanceModelView):
|
||||
model = Comment
|
||||
serializer_class = CommentSerializer
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user