Skip to content

Commit ec6c891

Browse files
match with front-end
1 parent 26d45e9 commit ec6c891

File tree

8 files changed

+67
-7
lines changed

8 files changed

+67
-7
lines changed

classroom/business/teacher/classroom.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import secrets
22

3+
from django.conf import settings
34
from django.contrib.auth import get_user_model
45

56
from classroom.tasks import send_temp_password_for_new_students_task
@@ -51,3 +52,20 @@ def add_reading_exercises_to_classroom(classroom, exercise_pks, user):
5152

5253
def remove_reading_exercises_to_classroom(classroom, exercise_pks):
5354
classroom.reading_exercises.remove(*exercise_pks)
55+
56+
def upload_reading_exercise_image(image, request=None):
57+
path = settings.MEDIA_ROOT / 'classroom' / 'reading_exercises' / 'uploaded_images' / image.name
58+
path.parent.mkdir(parents=True, exist_ok=True)
59+
if path.exists():
60+
unique_name = path.stem + secrets.token_urlsafe(nbytes=8)
61+
path = path.parent / f'{unique_name}{path.suffix}'
62+
63+
with open(path, 'wb+') as destination:
64+
for chunk in image.chunks():
65+
destination.write(chunk)
66+
67+
rpath = path.relative_to(settings.BASE_DIR)
68+
url = '/' + str(rpath).replace('\\', '/')
69+
if request:
70+
url = request.build_absolute_uri(url)
71+
return url

classroom/models/abstracts/question.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ def get_answers_content(self):
5959
answers.append(answer.content)
6060
return answers
6161

62+
def get_choices_content(self):
63+
return self.choices.split(self._DELEMITER)
64+
65+
@classmethod
66+
def generate_choices_from_list(cls, choices):
67+
return cls._DELEMITER.join(choices)
68+
6269
def check_answer(self, answer):
6370
# NOTE: don't use .values_list('content', flat=True) here,
6471
# because it will not utilize .prefetch_related('answers'),

classroom/models/reading_question.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ def __str__(self):
1616
return f'{self.exercise.identifier} | {self.get_question_type_display()}'
1717

1818
def create_answers(self, answers):
19-
contents = answers.split(self._DELEMITER)
2019
answers_objs = [
2120
ReadingAnswer(question=self, content=content)
22-
for content in contents
21+
for content in answers
2322
]
2423
ReadingAnswer.objects.bulk_create(answers_objs)
2524

classroom/serializers/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
RemoveStudentSerializer,
44
StudentReadingReportSerializer)
55
from .exercise import (ReadingExerciseSerializer,
6-
ReadingExerciseSubmitSerializer)
6+
ReadingExerciseSubmitSerializer,
7+
ReadingExerciseUploadImgSerializer)
78
from .question import ReadingQuestionSerializer
89
from .reading_submission import ReadingSubmissionSerializer

classroom/serializers/classroom.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22
from rest_framework import serializers
33

44
from account.serializers import UserSerializer
5-
from classroom.models import Classroom
5+
from classroom.models import Classroom, ReadingExercise
66
from classroom.utils.serializer import ValidateUniqueTogetherMixin
77

88

99
class ClassroomSerializer(ValidateUniqueTogetherMixin, serializers.HyperlinkedModelSerializer):
1010
teacher = UserSerializer(read_only=True)
1111
students = UserSerializer(many=True, read_only=True)
12+
reading_exercises = serializers.PrimaryKeyRelatedField(
13+
queryset=ReadingExercise.objects.all(),
14+
many=True,
15+
)
1216

1317
class Meta:
1418
model = Classroom
@@ -22,7 +26,7 @@ class Meta:
2226
]
2327
extra_kwargs = {
2428
'url': {'view_name': 'classroom-detail'},
25-
'reading_exercises': {'view_name': 'reading-exercise-detail'},
29+
# 'reading_exercises': {'view_name': 'reading-exercise-detail'},
2630
}
2731

2832
def validate_name(self, name):

classroom/serializers/exercise.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,11 @@ class ReadingExerciseSubmitSerializer(serializers.Serializer):
5858

5959
class Meta:
6060
list_serializer_class = _SubmitAnswerListSerializer
61+
62+
63+
class ReadingExerciseUploadImgSerializer(serializers.Serializer):
64+
image = serializers.ImageField(write_only=True)
65+
image_url = serializers.URLField(read_only=True)
66+
67+
def validate_image(self, image):
68+
return image # TODO

classroom/serializers/question.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66

77
class ReadingQuestionSerializer(serializers.HyperlinkedModelSerializer):
8-
answers = serializers.CharField(source='get_answers_content')
8+
choices = serializers.ListField(source='get_choices_content')
9+
answers = serializers.ListField(source='get_answers_content')
910

1011
class Meta:
1112
model = ReadingQuestion
@@ -25,6 +26,7 @@ def validate(self, attrs):
2526
attrs = super().validate(attrs)
2627
self._validate_question_not_exist(attrs)
2728
self._handle_get_answers_content(attrs)
29+
self._handle_get_choices_content(attrs)
2830
return attrs
2931

3032
def _validate_question_not_exist(self, attrs):
@@ -52,6 +54,11 @@ def _handle_get_answers_content(self, attrs):
5254
if 'get_answers_content' in attrs:
5355
attrs['answers'] = attrs.pop('get_answers_content')
5456

57+
def _handle_get_choices_content(self, attrs):
58+
if 'get_choices_content' in attrs:
59+
choices = attrs.pop('get_choices_content')
60+
attrs['choices'] = ReadingQuestion.generate_choices_from_list(choices)
61+
5562
def create(self, validated_data):
5663
has_answers = 'answers' in validated_data
5764
if has_answers:

classroom/views/exercise.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
from rest_framework.response import Response
33
from rest_framework.viewsets import ModelViewSet
44

5+
from classroom.business.teacher import classroom as business
56
from classroom.filters import ReadingExerciseFilter
67
from classroom.models import ReadingExercise
78
from classroom.permissions import IsStudent, IsTeacherOrReadOnly
89
from classroom.serializers import (ReadingExerciseSerializer,
9-
ReadingExerciseSubmitSerializer)
10+
ReadingExerciseSubmitSerializer,
11+
ReadingExerciseUploadImgSerializer)
1012

1113

1214
class ReadingExerciseViewSet(ModelViewSet):
@@ -30,3 +32,17 @@ def submit_answers(self, request, pk):
3032
exercise = self.get_object()
3133
serializer.save(exercise=exercise)
3234
return Response()
35+
36+
@action(
37+
methods=['POST'], detail=False, url_path='upload-image',
38+
serializer_class=ReadingExerciseUploadImgSerializer,
39+
)
40+
def upload_image(self, request):
41+
"""Upload image used in reading exercise
42+
"""
43+
serializer = self.get_serializer(data=request.data)
44+
serializer.is_valid(raise_exception=True)
45+
image = serializer.validated_data['image']
46+
image_url = business.upload_reading_exercise_image(image, request=request)
47+
serializer = self.get_serializer(instance={'image_url': image_url})
48+
return Response(serializer.data)

0 commit comments

Comments
 (0)