Skip to content

Commit

Permalink
Merge pull request #628 from bounswe/BACKEND-627
Browse files Browse the repository at this point in the history
feat(backend): improve quiz result endpoint and add quiz review endpoint
  • Loading branch information
aoengin authored Nov 24, 2024
2 parents 036e9ba + f1c6eda commit 372b973
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 29 deletions.
33 changes: 17 additions & 16 deletions backend/app/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 4.2.16 on 2024-11-24 11:52
# Generated by Django 4.2.16 on 2024-11-24 15:14

from django.conf import settings
import django.contrib.postgres.fields
Expand Down Expand Up @@ -33,6 +33,21 @@ class Migration(migrations.Migration):
('liked_by', models.ManyToManyField(blank=True, related_name='liked_quizzes', to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='QuizProgress',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('score', models.FloatField(default=0)),
('quiz_attempt', models.IntegerField(default=0)),
('date_started', models.DateTimeField(default=django.utils.timezone.now)),
('completed', models.BooleanField(default=False)),
('quiz', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='progress', to='app.quiz')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quiz_progress', to=settings.AUTH_USER_MODEL)),
],
options={
'unique_together': {('quiz', 'user', 'quiz_attempt')},
},
),
migrations.CreateModel(
name='Tags',
fields=[
Expand Down Expand Up @@ -76,24 +91,10 @@ class Migration(migrations.Migration):
('score', models.FloatField()),
('time_taken', models.IntegerField()),
('quiz', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='results', to='app.quiz')),
('quiz_progress', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='results', to='app.quizprogress')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='results', to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='QuizProgress',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('score', models.FloatField(default=0)),
('quiz_attempt', models.IntegerField(default=0)),
('date_started', models.DateTimeField(default=django.utils.timezone.now)),
('completed', models.BooleanField(default=False)),
('quiz', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='progress', to='app.quiz')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quiz_progress', to=settings.AUTH_USER_MODEL)),
],
options={
'unique_together': {('quiz', 'user', 'quiz_attempt')},
},
),
migrations.AddField(
model_name='quiz',
name='tags',
Expand Down
1 change: 1 addition & 0 deletions backend/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def __str__(self):
class QuizResults(models.Model):
id = models.AutoField(primary_key=True)
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE, related_name='results')
quiz_progress = models.ForeignKey(QuizProgress, on_delete=models.CASCADE, related_name='results')
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='results')
score = models.FloatField()
time_taken = models.IntegerField()
Expand Down
3 changes: 2 additions & 1 deletion backend/app/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,15 @@ def update(self, instance, validated_data):
class QuizResultsSerializer(serializers.ModelSerializer):
class Meta:
model = QuizResults
fields = ['id', 'quiz', 'user', 'score', 'time_taken']
fields = ['id', 'quiz', 'quiz_progress', 'user', 'score', 'time_taken']

def to_representation(self, instance):
representation = super().to_representation(instance)
representation['quiz'] = { 'id' : instance.quiz.id, 'title' : instance.quiz.title }
representation['question_count'] = instance.quiz.question_count
representation['user'] = { 'id' : instance.user.id, 'username' : instance.user.username }
representation['author'] = { 'id' : instance.quiz.author.id, 'username' : instance.quiz.author.username }
representation['level'] = instance.quiz.level
return representation


Expand Down
5 changes: 3 additions & 2 deletions backend/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
path('', index , name='index_page'),
path('profile/', view_profile, name='view_profile'),
path('profile/update/', update_profile, name='update_profile'),
path('quiz/<int:quiz_id>', quiz_views.get_quiz, name="get_quiz"),
path('quiz/<int:quiz_id>/', quiz_views.get_quiz, name="get_quiz"),
path('feed/quiz/', quiz_views.view_quizzes, name="feed_quiz"),
path('quiz/create/', quiz_views.create_quiz, name="create_quiz"),
path('quiz/question/', quiz_views.get_question, name="get_question"),
Expand All @@ -28,11 +28,12 @@
path('quiz/results/', quiz_views.get_quiz_results, name="get_quiz_results"),
path('quiz/like/', quiz_views.like_quiz, name="like_quiz"),
path('quiz/bookmark/', quiz_views.bookmark_quiz, name="bookmark_quiz"),
path('quiz/result/<int:quiz_progress_id>/', quiz_views.get_specific_quiz_result, name="get_specific_quiz_result"),
path('quiz/result/<int:quiz_result_id>/', quiz_views.get_specific_quiz_result, name="get_specific_quiz_result"),
path('quiz/bookmarks/', quiz_views.view_bookmarked_quizzes, name="view_bookmarked_quizzes"),
path('quiz/likes/', quiz_views.view_liked_quizzes, name="view_bookmarked_quizzes"),
path('quiz/created/<str:username>/', quiz_views.view_created_quizzes, name="view_created_quizzes"),
path('quiz/solved/<str:username>/', quiz_views.view_solved_quizzes, name="view_solved_quizzes"),
path('quiz/review/<int:quiz_result_id>/', quiz_views.get_quiz_review, name="review_quiz"),


path('create-post/',create_post, name='create_post'),
Expand Down
37 changes: 27 additions & 10 deletions backend/app/views_directory/quiz_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def submit_quiz(request):

quiz_result_serializer = QuizResultsSerializer(data={
'quiz': quiz.id,
'quiz_progress': quiz_progress.id,
'user': request.user.id,
'score': score,
'time_taken': quiz_progress.quiz_attempt
Expand Down Expand Up @@ -104,19 +105,33 @@ def get_quiz_results(request):

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_specific_quiz_result(request, quiz_progress_id):
"""
Retrieves the quiz result for the authenticated user for the given quiz ID.
"""
# Fetch the quiz to validate its existence
def get_specific_quiz_result(request, quiz_result_id):

# Fetch the quiz result for the authenticated user
quiz_result = get_object_or_404(QuizResults, id=quiz_progress_id, user=request.user)
quiz_result = get_object_or_404(QuizResults, id=quiz_result_id, user=request.user)

# Serialize and return the quiz result
serializer = QuizResultsSerializer(quiz_result)
return Response(serializer.data, status=status.HTTP_200_OK)

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_quiz_review(request, quiz_result_id):
quiz_progress = get_object_or_404(QuizResults, id=quiz_result_id, user=request.user).quiz_progress
quiz = quiz_progress.quiz
question_progresses = QuestionProgress.objects.filter(quiz_progress=quiz_progress)
data = {'questions': []}
for question_progress in question_progresses:
question = get_object_or_404(Question, id=question_progress.question.id)
data['questions'].append({'question': question.question_text,
'choices': [question.choice1, question.choice2,
question.choice3, question.choice4],
'question_number': question.question_number,
'correct_choice': question.correct_choice,
'previous_answer': question_progress.answer})
data["quiz_progress_id"] = quiz_progress.id
data["quiz_title"] = quiz.title
data["question_count"] = quiz.question_count
return Response(data, status=status.HTTP_200_OK)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def start_quiz(request):
Expand Down Expand Up @@ -215,8 +230,10 @@ def get_question(request):
def get_quiz(request, quiz_id):
quiz = get_object_or_404(Quiz, id=quiz_id)
serializer = QuizSerializer(quiz, context = {'request': request})

return Response(serializer.data, status=status.HTTP_200_OK)
data = {'quiz': serializer.data}
data['is_solved'] = QuizProgress.objects.filter(quiz=quiz, user=request.user, completed=True).exists()
data['quiz_result_id'] = QuizResults.objects.filter(quiz=quiz, user=request.user).order_by('-id').first().id if data['is_solved'] else None
return Response(data, status=status.HTTP_200_OK)



Expand Down

0 comments on commit 372b973

Please sign in to comment.