From 95b6ac712b81bc7776825bc8dce7dee010246c35 Mon Sep 17 00:00:00 2001 From: Piotr Dobrowolski Date: Mon, 6 Mar 2017 16:50:55 +0100 Subject: [PATCH] Initial public REST API --- requirements.txt | 2 ++ spejstore/settings.py | 12 ++++++++++++ spejstore/urls.py | 10 ++++++++++ storage/apiviews.py | 35 +++++++++++++++++++++++++++++++++++ storage/serializers.py | 9 +++++++++ 5 files changed, 68 insertions(+) create mode 100644 storage/apiviews.py create mode 100644 storage/serializers.py diff --git a/requirements.txt b/requirements.txt index 09dc122..771e61a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,5 +3,7 @@ git+https://github.com/djangonauts/django-hstore@61427e474cb2f4be8fdfce225d78a53 django-appconf==1.0.2 django-auth-ldap==1.2.9 Django-Select2==5.8.10 +djangorestframework==3.5.4 Pillow==3.3.1 psycopg2==2.6.2 +djangorestframework-hstore==1.3 diff --git a/spejstore/settings.py b/spejstore/settings.py index c89e2e9..7aa620f 100644 --- a/spejstore/settings.py +++ b/spejstore/settings.py @@ -42,6 +42,7 @@ INSTALLED_APPS = [ 'django_hstore', 'tree', 'django_select2', + 'rest_framework', 'storage', ] @@ -109,6 +110,8 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] +# LDAP configuration + import ldap from django_auth_ldap.config import LDAPSearch, GroupOfUniqueNamesType @@ -170,3 +173,12 @@ STATICFILES_DIRS = [ MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, "media") + +# REST Framework +REST_FRAMEWORK = { + # Use Django's standard `django.contrib.auth` permissions, + # or allow read-only access for unauthenticated users. + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly' + ] +} diff --git a/spejstore/urls.py b/spejstore/urls.py index 5645533..8fec492 100644 --- a/spejstore/urls.py +++ b/spejstore/urls.py @@ -8,12 +8,22 @@ from django.contrib import admin from django.conf import settings from django.conf.urls.static import static +from rest_framework import routers +from storage import apiviews + + +router = routers.DefaultRouter() +router.register(r'items', apiviews.ItemViewSet) + +# Wire up our API using automatic URL routing. +# Additionally, we include login URLs for the browsable API. urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^select2/', include('django_select2.urls')), url(r'^', include('storage.urls')), + url(r'^api/1/', include(router.urls)), ] \ + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) \ + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/storage/apiviews.py b/storage/apiviews.py new file mode 100644 index 0000000..7738f5d --- /dev/null +++ b/storage/apiviews.py @@ -0,0 +1,35 @@ +from rest_framework import viewsets, generics +from rest_framework.response import Response +from rest_framework.decorators import detail_route + +from storage.models import Item +from storage.serializers import ItemSerializer +from django.shortcuts import get_object_or_404 + + +class ItemViewSet(viewsets.ModelViewSet): + """ + API endpoint that allows items to be viewed or edited. + """ + queryset = Item.objects + serializer_class = ItemSerializer + + def get_queryset(self): + return Item.get_roots() + + def get_object(self): + lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field + + obj = get_object_or_404(Item, pk=self.kwargs[lookup_url_kwarg]) + self.check_object_permissions(self.request, obj) + + return obj + + @detail_route() + def children(self, request, pk): + """ + Returns a list of all the group names that the given + user belongs to. + """ + item = self.get_object() + return Response(self.serializer_class(item.get_children().all(), many=True).data) diff --git a/storage/serializers.py b/storage/serializers.py new file mode 100644 index 0000000..384e35b --- /dev/null +++ b/storage/serializers.py @@ -0,0 +1,9 @@ +from storage.models import Item +from rest_framework import serializers +from rest_framework_hstore.serializers import HStoreSerializer + + +class ItemSerializer(HStoreSerializer): + class Meta: + model = Item + fields = ('uuid', 'name', 'description', 'props', 'state', 'parent')