From 7aa226d5ac3c0e8be0d1709fdd6ad0ee175c922c Mon Sep 17 00:00:00 2001 From: yleclanche Date: Thu, 18 Jul 2019 17:31:34 +0200 Subject: [PATCH] Add REST support --- teleforma/middleware.py | 4 +- teleforma/rest.py | 174 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 teleforma/rest.py diff --git a/teleforma/middleware.py b/teleforma/middleware.py index 61ec3ef2..187c09de 100644 --- a/teleforma/middleware.py +++ b/teleforma/middleware.py @@ -30,7 +30,7 @@ try: except: XS_SHARING_ALLOWED_ORIGINS = '*' XS_SHARING_ALLOWED_METHODS = ['POST','GET','OPTIONS', 'PUT', 'DELETE'] - XS_SHARING_ALLOWED_HEADERS = ['Origin', 'Content-Type', 'Accept'] + XS_SHARING_ALLOWED_HEADERS = ['Origin', 'Content-Type', 'Accept', 'Authorization'] class XsSharing(object): @@ -63,3 +63,5 @@ class XsSharing(object): response['Access-Control-Allow-Headers'] = ",".join( XS_SHARING_ALLOWED_HEADERS ) return response + + diff --git a/teleforma/rest.py b/teleforma/rest.py new file mode 100644 index 00000000..28a80590 --- /dev/null +++ b/teleforma/rest.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- + +from django.conf.urls import url, include +from django.contrib.auth.models import User +from django.shortcuts import get_object_or_404 +from django.http import Http404 +from rest_framework import routers, serializers, viewsets +from rest_framework.authtoken.views import ObtainAuthToken +from rest_framework.authtoken.models import Token +from rest_framework.response import Response +from rest_framework.decorators import list_route + +# Serializers define the API representation. +from teleforma.models.core import Course, CourseType, Period, Media, MediaItem, Conference, Document +from teleforma.models.crfpa import Student +from teleforma.views.core import get_courses + + +class UserSerializer(serializers.ModelSerializer): + class Meta: + model = User + fields = ('url', 'username', 'email', 'is_staff', 'student') + + +class StudentSerializer(serializers.ModelSerializer): + class Meta: + model = Student + fields = ('id', 'period') + + +# class TokenSerializer(serializers.HyperlinkedModelSerializer): +# class Meta: +# model = Token + +class UserViewSet(viewsets.ModelViewSet): + queryset = User.objects.all() + serializer_class = UserSerializer + + @list_route() + def get_from_token(self, request): + token = get_object_or_404(Token.objects.all(), pk=request.query_params.get('token')) + serializer = UserSerializer(token.user, context={'request': request}) + return Response(serializer.data) + + +class StudentViewSet(viewsets.ModelViewSet): + queryset = Student.objects.all() + serializer_class = StudentSerializer + + +router = routers.DefaultRouter() +router.register(r'users', UserViewSet) +router.register(r'students', StudentViewSet) + + +class CRFPAAuthToken(ObtainAuthToken): + + def post(self, request, *args, **kwargs): + serializer = self.serializer_class(data=request.data, + context={'request': request}) + serializer.is_valid(raise_exception=True) + user = serializer.validated_data['user'] + token, created = Token.objects.get_or_create(user=user) + serializer = UserSerializer(token.user, context={'request': request}) + data = serializer.data + data['token'] = token.key + return Response(data) + + +class ConferenceSerializer(serializers.ModelSerializer): + professor = serializers.StringRelatedField() + + class Meta: + model = Conference + fields = ('id', 'session', 'professor', 'date_begin', 'comment') + + +class MediaItemSerializer(serializers.ModelSerializer): + class Meta: + model = MediaItem + fields = ('id', 'title', 'file') + + +class MediaSerializer(serializers.ModelSerializer): + item = MediaItemSerializer() + conference = ConferenceSerializer() + + class Meta: + model = Media + +class DocumentSerializer(serializers.ModelSerializer): + type = serializers.StringRelatedField() + + class Meta: + model = Document + +class CourseListSerializer(serializers.ModelSerializer): + class Meta: + model = Course + fields = ('url', 'id', 'title') + +class CourseSerializer(serializers.ModelSerializer): + class Meta: + model = Course + # fields = ('url', 'id', 'title', 'period', 'session') + + def to_representation(self, instance): + """Convert `username` to lowercase.""" + request = self.context['request'] + ret = super(CourseSerializer, self).to_representation(instance) + course_types = CourseType.objects.all() + ret['course_types'] = [] + for ctype in course_types: + data = { + 'id': ctype.id, + 'title': ctype.name + } + medias = Media.objects.filter(course=instance, course_type=ctype, period__id=request.query_params['period'], type='webm', + is_published=True) + docs = Document.objects.filter(course=instance, course_type=ctype, periods__id=request.query_params['period'], is_published=True) + data['medias'] = MediaSerializer(medias, many=True).data + data['docs'] = DocumentSerializer(docs, many=True).data + ret['course_types'].append(data) + return ret + + +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status + + +class CourseViewSet(viewsets.ReadOnlyModelViewSet): + serializer_class = CourseSerializer + + def list(self, request, format=None): + period_id = request.query_params.get('period') + period = None + if period_id: + period = Period.objects.get(pk=int(period_id)) + if not period: + raise Http404('Missing period') + courses = [course['course'] for course in get_courses(self.request.user, num_order=True, period=period)] + serializer = CourseListSerializer(courses, many=True, context={'request': request}) + return Response(serializer.data) + + def retrieve(self, request, pk=None): + queryset = Course.objects.all() + # TODO : security check + if 'period' not in self.request.query_params: + raise Http404('Missing period') + + course = get_object_or_404(queryset, pk=pk) + serializer = CourseSerializer(course, context={'request': request}) + print + serializer.data + return Response(serializer.data) + + +router.register(r'courses', CourseViewSet, base_name='course') + +# class CourseDetail(APIView): +# """ +# Retrieve, update or delete a snippet instance. +# """ +# def get_object(self, pk): +# try: +# return Course.objects.get(pk=pk) +# except Snippet.DoesNotExist: +# raise Http404 +# +# def get(self, request, pk, format=None): +# snippet = self.get_object(pk) +# serializer = SnippetSerializer(snippet) +# return Response(serializer.data) -- 2.39.5