Created
January 22, 2015 08:09
-
-
Save rombr/256e769bbe752aabfd8d to your computer and use it in GitHub Desktop.
Django REST framework example code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding:utf-8 -*- | |
from django.http import Http404 | |
from django.conf import settings | |
import mongoengine | |
from rest_framework import viewsets | |
from rest_framework.response import Response | |
from rest_framework import status | |
from sx.apps.schemes import backend | |
from sx.apps.schemes.backends import SchemeNotFoundError | |
from sx.apps.schemes.const import SCHEME_TYPE_DATA, SCHEME_TYPE_REVIEW | |
from proxy import CommonReview | |
import proxy | |
from forms import FilterForm | |
class ReviewViewSet(viewsets.ViewSet): | |
''' | |
CRUD-API for reviews | |
''' | |
def get_object(self, Model, pk): | |
try: | |
return Model.objects.get(pk=pk) | |
except (Model.DoesNotExist, | |
# pk is not a valid ObjectId | |
mongoengine.ValidationError): | |
raise Http404 | |
def get_model_or_errors(self, data): | |
''' | |
Get review model for operation, | |
that changes data | |
Return: | |
<ModelClass>, <ErrorDict> | |
''' | |
data_scheme_name = data.get('type', None) | |
review_scheme_name = data.get('scheme', None) | |
try: | |
backend.get_scheme(data_scheme_name, | |
SCHEME_TYPE_DATA) | |
except SchemeNotFoundError: | |
return None, {'type': [u'Invalid type', ], } | |
try: | |
backend.get_scheme(review_scheme_name, | |
SCHEME_TYPE_REVIEW) | |
except SchemeNotFoundError: | |
return None, {'scheme': [u'Invalid scheme', ], } | |
return getattr(proxy, '%sReview' % review_scheme_name.capitalize()), {} | |
def obj_to_dict(self, obj): | |
''' | |
Mongo object to dict | |
''' | |
if isinstance(obj, mongoengine.QuerySet): | |
return [self.obj_to_dict(i) for i in obj] | |
else: | |
result_obj = obj.to_mongo() | |
if '_id' in result_obj: | |
result_obj['id'] = str(result_obj['_id']) | |
del result_obj['_id'] | |
return result_obj | |
def list(self, request, format=None): | |
''' | |
Reviews list | |
''' | |
try: | |
skip = int(request.GET.get('skip', None)) | |
except (ValueError, TypeError): | |
skip = 0 | |
try: | |
limit = int(request.GET.get('limit', None)) | |
except (ValueError, TypeError): | |
limit = settings.PER_PAGE | |
form = FilterForm(data=request.GET) | |
if form.is_valid(): | |
lookups = {k: v for k, v in form.cleaned_data.iteritems() if v} | |
else: | |
return Response(form.errors, status=status.HTTP_400_BAD_REQUEST) | |
if lookups: | |
total = CommonReview.objects(**lookups).count() | |
reviews = CommonReview.objects(**lookups)[skip:skip + limit] | |
else: | |
total = CommonReview.objects.all().count() | |
reviews = CommonReview.objects.all()[skip:skip + limit] | |
return Response({ | |
'total': total, | |
'objects': self.obj_to_dict(reviews), | |
}) | |
def create(self, request, format=None): | |
''' | |
Create new review | |
''' | |
ReviewModel, errors = self.get_model_or_errors(request.DATA) | |
if errors: | |
return Response(errors, status=status.HTTP_400_BAD_REQUEST) | |
try: | |
obj = ReviewModel(**request.DATA) | |
obj.save() | |
return Response(self.obj_to_dict(obj), | |
status=status.HTTP_201_CREATED) | |
except (mongoengine.ValidationError) as e: | |
return Response(e.to_dict(), status=status.HTTP_400_BAD_REQUEST) | |
def retrieve(self, request, pk=None, format=None): | |
''' | |
Review details | |
''' | |
obj = self.get_object(CommonReview, pk) | |
return Response(self.obj_to_dict(obj)) | |
def update(self, request, pk=None, format=None): | |
''' | |
Update review | |
''' | |
# May be need in clean of model (?) | |
if 'type' in request.DATA: | |
data_scheme_name = request.DATA.get('type', None) | |
try: | |
backend.get_scheme(data_scheme_name, SCHEME_TYPE_DATA) | |
except SchemeNotFoundError: | |
return None, {'type': [u'Invalid type', ], } | |
if 'scheme' in request.DATA: | |
review_scheme_name = request.DATA.get('scheme', None) | |
try: | |
backend.get_scheme(review_scheme_name, SCHEME_TYPE_REVIEW) | |
except SchemeNotFoundError: | |
return None, {'scheme': [u'Invalid scheme', ], } | |
try: | |
scheme_name = CommonReview.objects.only('scheme').get(pk=pk).scheme | |
except (CommonReview.DoesNotExist, | |
# pk is not a valid ObjectId | |
mongoengine.ValidationError): | |
raise Http404 | |
ReviewModel = getattr(proxy, '%sReview' % scheme_name.capitalize()) | |
obj = self.get_object(ReviewModel, pk) | |
try: | |
obj.update_with_dict(request.DATA) | |
obj.save() | |
# Fix this case: | |
# created == updated | |
obj = self.get_object(CommonReview, pk) | |
return Response(self.obj_to_dict(obj)) | |
except (mongoengine.ValidationError) as e: | |
return Response(e.to_dict(), status=status.HTTP_400_BAD_REQUEST) | |
def partial_update(self, request, pk=None, format=None): | |
''' | |
Update review | |
''' | |
return self.update(request, pk, format) | |
def destroy(self, request, pk=None, format=None): | |
''' | |
Delete review | |
''' | |
obj = self.get_object(CommonReview, pk) | |
obj.delete() | |
return Response(status=status.HTTP_204_NO_CONTENT) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment