Commit 6e219159 by Tom Christie

First pass at mixins & generic views

parent a092a728
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)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class CommentInstance(mixins.RetrieveModelInstanceMixin,
mixins.UpdateModelInstanceMixin,
mixins.DestroyModelInstanceMixin,
views.BaseInstanceAPIView):
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment