diff --git a/docker-compose.yml b/docker-compose.yml index aa71e8e..a34618d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ services: - "8083:8000" # Expose port 8083 for the web server environment: - PYTHONBUFFERED=1 - command: ["sh", "-c", "python stude/manage.py collectstatic --noinput && python stude/manage.py makemigrations && python stude/manage.py custom_migrate && python stude/manage.py runserver"] + command: ["sh", "-c", "python stude/manage.py spectacular --color --file stude/schema.yml && python stude/manage.py collectstatic --noinput && python stude/manage.py makemigrations && python stude/manage.py custom_migrate && python stude/manage.py runserver"] volumes: - .:/code # For hotreloading depends_on: diff --git a/stude/schema.yml b/stude/schema.yml index 80fd7b9..c8aaa04 100644 --- a/stude/schema.yml +++ b/stude/schema.yml @@ -763,21 +763,22 @@ paths: items: $ref: '#/components/schemas/StudyGroup' description: '' + /api/v1/study_groups/create//: post: - operationId: api_v1_study_groups_create + operationId: api_v1_study_groups_create_create tags: - api requestBody: content: application/json: schema: - $ref: '#/components/schemas/StudyGroup' + $ref: '#/components/schemas/StudyGroupCreate' application/x-www-form-urlencoded: schema: - $ref: '#/components/schemas/StudyGroup' + $ref: '#/components/schemas/StudyGroupCreate' multipart/form-data: schema: - $ref: '#/components/schemas/StudyGroup' + $ref: '#/components/schemas/StudyGroupCreate' required: true security: - jwtAuth: [] @@ -786,48 +787,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/StudyGroup' - description: '' - put: - operationId: api_v1_study_groups_update - tags: - - api - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/StudyGroup' - application/x-www-form-urlencoded: - schema: - $ref: '#/components/schemas/StudyGroup' - multipart/form-data: - schema: - $ref: '#/components/schemas/StudyGroup' - required: true - security: - - jwtAuth: [] - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/StudyGroup' + $ref: '#/components/schemas/StudyGroupCreate' description: '' + /api/v1/study_groups/create//{id}/: patch: - operationId: api_v1_study_groups_partial_update + operationId: api_v1_study_groups_create_partial_update + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this study group. + required: true tags: - api requestBody: content: application/json: schema: - $ref: '#/components/schemas/PatchedStudyGroup' + $ref: '#/components/schemas/PatchedStudyGroupCreate' application/x-www-form-urlencoded: schema: - $ref: '#/components/schemas/PatchedStudyGroup' + $ref: '#/components/schemas/PatchedStudyGroupCreate' multipart/form-data: schema: - $ref: '#/components/schemas/PatchedStudyGroup' + $ref: '#/components/schemas/PatchedStudyGroupCreate' security: - jwtAuth: [] responses: @@ -835,10 +819,17 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/StudyGroup' + $ref: '#/components/schemas/StudyGroupCreate' description: '' delete: - operationId: api_v1_study_groups_destroy + operationId: api_v1_study_groups_create_destroy + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this study group. + required: true tags: - api security: @@ -1175,7 +1166,7 @@ components: landmark: type: string nullable: true - PatchedStudyGroup: + PatchedStudyGroupCreate: type: object properties: id: @@ -1187,6 +1178,9 @@ components: type: array items: type: string + description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_ + only. + nullable: true subject: type: string location: @@ -1194,9 +1188,6 @@ components: landmark: type: string nullable: true - radius: - type: number - format: double active: type: boolean timestamp: @@ -1345,6 +1336,41 @@ components: - students - subject - timestamp + StudyGroupCreate: + type: object + properties: + id: + type: integer + readOnly: true + name: + type: string + students: + type: array + items: + type: string + description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_ + only. + nullable: true + subject: + type: string + location: + type: string + landmark: + type: string + nullable: true + active: + type: boolean + timestamp: + type: string + format: date + readOnly: true + required: + - id + - location + - name + - students + - subject + - timestamp SubjectInstance: type: object properties: diff --git a/stude/study_groups/serializers.py b/stude/study_groups/serializers.py index 4aa0f00..caaa3ea 100644 --- a/stude/study_groups/serializers.py +++ b/stude/study_groups/serializers.py @@ -23,10 +23,33 @@ class StudyGroupSerializer(serializers.ModelSerializer): queryset=Landmark.objects.all(), many=False, slug_field='name', required=False, allow_null=True) radius = serializers.FloatField() + class Meta: + model = StudyGroup + fields = '__all__' + read_only_fields = ['landmark', 'radius', 'students'] + + +class FullNameSlugRelatedField(serializers.SlugRelatedField): + def to_representation(self, instance): + return instance.full_name + + +class StudyGroupCreateSerializer(serializers.ModelSerializer): + name = serializers.CharField() + subject = serializers.SlugRelatedField( + many=False, slug_field='name', queryset=Subject.objects.all(), required=True, allow_null=False) + location = PointField() + landmark = serializers.SlugRelatedField( + queryset=Landmark.objects.all(), many=False, slug_field='name', required=False, allow_null=True) + def create(self, validated_data): user = self.context['request'].user study_group = StudyGroup.objects.create( - users=[user], defaults=validated_data) + name=validated_data['name'], location=validated_data['location'], subject=validated_data['subject']) + for landmark in Landmark.objects.all(): + if landmark.location.contains(validated_data['location']): + validated_data['landmark'] = landmark + break validated_data['location'].read_only = True return study_group @@ -41,4 +64,4 @@ class StudyGroupSerializer(serializers.ModelSerializer): class Meta: model = StudyGroup fields = '__all__' - read_only_fields = ['landmark', 'radius', 'students'] + read_only_fields = ['landmark'] diff --git a/stude/study_groups/urls.py b/stude/study_groups/urls.py index 5a57a5e..9bee14f 100644 --- a/stude/study_groups/urls.py +++ b/stude/study_groups/urls.py @@ -1,7 +1,13 @@ from django.urls import include, path -from .views import StudyGroupListView, StudyGroupListNearView +from .views import StudyGroupListView, StudyGroupListNearView, StudyGroupCreateView +from rest_framework import routers + +router = routers.DefaultRouter() +router.register(r'create', StudyGroupCreateView, + basename='Create Study Group') urlpatterns = [ path('', StudyGroupListView.as_view()), path('near/', StudyGroupListNearView.as_view()), + path('', include(router.urls)), ] diff --git a/stude/study_groups/views.py b/stude/study_groups/views.py index 5022753..2388fec 100644 --- a/stude/study_groups/views.py +++ b/stude/study_groups/views.py @@ -2,7 +2,7 @@ from django.shortcuts import render from rest_framework import generics, mixins from rest_framework.exceptions import PermissionDenied from rest_framework.permissions import IsAuthenticated -from .serializers import StudyGroupSerializer +from .serializers import StudyGroupSerializer, StudyGroupCreateSerializer from .models import StudyGroup from subjects.models import Subject, SubjectInstance from student_status.models import StudentStatus @@ -16,7 +16,14 @@ from rest_framework import permissions # Create your views here. -class StudyGroupListView(generics.ListCreateAPIView, generics.UpdateAPIView, generics.DestroyAPIView): +class StudyGroupCreateView(viewsets.ModelViewSet): + http_method_names = ['patch', 'post', 'delete'] + permission_classes = [IsAuthenticated] + serializer_class = StudyGroupCreateSerializer + queryset = StudyGroup.objects.all() + + +class StudyGroupListView(generics.ListAPIView): permission_classes = [IsAuthenticated] serializer_class = StudyGroupSerializer queryset = StudyGroup.objects.all()