From 883dfda1473c9e020966827a2e7790d5060189b0 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Tue, 6 Mar 2018 13:41:30 +0300 Subject: [PATCH] Add site dynamic configs api --- api/v1/serializers/config.py | 38 ++++++++++++++++++++++++++++++++++++ api/v1/urls.py | 7 +++++-- api/v1/views.py | 22 ++++++++++++++++++++- 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 api/v1/serializers/config.py diff --git a/api/v1/serializers/config.py b/api/v1/serializers/config.py new file mode 100644 index 00000000..92f8aa64 --- /dev/null +++ b/api/v1/serializers/config.py @@ -0,0 +1,38 @@ +from constance import config +from constance.admin import get_values, ConstanceForm +from rest_framework import serializers +from rest_framework.fields import SkipField +from collections import OrderedDict + + +def _set_constance_value(key, value): + form = ConstanceForm(initial=get_values()) + field = form.fields[key] + clean_value = field.clean(field.to_python(value)) + setattr(config, key, clean_value) + + +class ConfigSerializer(serializers.Serializer): + INSTAGRAM_CLIENT_ACCESS_TOKEN = serializers.CharField(required=False) + INSTAGRAM_CLIENT_SECRET = serializers.CharField(required=False) + INSTAGRAM_RESULTS_TAG = serializers.CharField(required=False) + INSTAGRAM_RESULTS_PATH = serializers.CharField(required=False) + SERVICE_COMMISSION = serializers.IntegerField(required=False) + + def to_representation(self, instance): + ret = OrderedDict() + fields = self._readable_fields + for field in fields: + attribute = instance.get(field.field_name) + ret[field.field_name] = field.to_representation(attribute) + return ret + + def to_internal_value(self, data): + ret = OrderedDict(get_values()) + for k, v in data.items(): + ret[k] = v + return ret + + def update(self, instance, validated_data): + for k, v in validated_data.items(): + _set_constance_value(k, v) diff --git a/api/v1/urls.py b/api/v1/urls.py index 572a90df..ab852c4d 100644 --- a/api/v1/urls.py +++ b/api/v1/urls.py @@ -8,7 +8,7 @@ from drf_yasg import openapi from .auth import ObtainToken from .views import ( - AuthorBalanceViewSet, + AuthorBalanceViewSet, ConfigViewSet, CategoryViewSet, CourseViewSet, MaterialViewSet, LikeViewSet, ImageViewSet, TextViewSet, @@ -38,6 +38,8 @@ router.register(r'school-schedules', SchoolScheduleViewSet, base_name='school-sc router.register(r'users', UserViewSet, base_name='users') +# router.register(r'configs', ConfigViewSet, base_name='configs') + schema_view = get_schema_view( openapi.Info( @@ -51,9 +53,10 @@ schema_view = get_schema_view( ) urlpatterns = [ + path('api-token-auth/', ObtainToken.as_view(), name='api-token-auth'), + path('configs/', ConfigViewSet.as_view(), name='configs'), path('swagger(.json|.yaml)', schema_view.without_ui(cache_timeout=None), name='schema-json'), path('swagger/', schema_view.with_ui('swagger', cache_timeout=None), name='schema-swagger-ui'), path('redoc/', schema_view.with_ui('redoc', cache_timeout=None), name='schema-redoc'), - path('api-token-auth/', ObtainToken.as_view(), name='api-token-auth'), path('', include((router.urls, 'api-root')), name='api-root'), ] diff --git a/api/v1/views.py b/api/v1/views.py index ad4b1402..68f0f428 100644 --- a/api/v1/views.py +++ b/api/v1/views.py @@ -1,12 +1,16 @@ +from constance.admin import get_values + from django.contrib.auth import get_user_model from rest_framework import status -from rest_framework import viewsets +from rest_framework import views, viewsets +from rest_framework import generics from rest_framework.decorators import detail_route, list_route from rest_framework.response import Response from . import ExtendedModelViewSet +from .serializers.config import ConfigSerializer from .serializers.course import ( CategorySerializer, LikeSerializer, CourseSerializer, CourseCreateSerializer, @@ -38,6 +42,7 @@ from apps.content.models import ( ) from apps.payment.models import AuthorBalance from apps.school.models import SchoolSchedule + User = get_user_model() @@ -309,3 +314,18 @@ class SchoolScheduleViewSet(ExtendedModelViewSet): queryset = SchoolSchedule.objects.all() serializer_class = SchoolScheduleSerializer permission_classes = (IsAdmin,) + + +class ConfigViewSet(generics.RetrieveUpdateAPIView): + serializer_class = ConfigSerializer + permission_classes = (IsAdmin,) + + def retrieve(self, request, *args, **kwargs): + serializer = ConfigSerializer(get_values()) + return Response(serializer.data) + + def patch(self, request, *args, **kwargs): + serializer = ConfigSerializer(data=request.data) + if serializer.is_valid(): + serializer.update(get_values(), serializer.validated_data) + return Response(serializer.data)