Skip to content

Commit

Permalink
feat(be): implement quiz and rate-quiz CRUD endpoints (#624)
Browse files Browse the repository at this point in the history
* feat(be): Created First Version of Quiz and QuizQuestion Endpoints, not tested

* feat(be): combine quiz and quiz question views, add tests for POST and GET

* chore(be): register the models on admin page so that they can be edited with a superuser

* refactor(be): move fixtures folder into core app

* refactor(be): minor changes in model data names

* data(be): add quiz and quiz question in data seed

* test(be): write unit tests for quiz

* fix(be): commented on quizquestion model as "will not be used"

* feat(be): added mock serializer fields on quiz to be implemented later such as num_taken, rating, is_taken

* test(be): implement take quiz (create) unit test

* feat(be): implement take quiz viewset

* fix(be): rename "Take" to "Rate" in every file and file name. I had wrongly named these as "TakeQuiz" while implementing "RateQuiz" instead

* fix(be): rename TakeQuiz to RateQuiz on admin page

* fix(be): rename the remaining "Take" to "Rate" Quiz

* feat(be): fix rate_quiz

* fix(be): update "author" field in permissions file to "user". This will cause conflicts and errors in other implementations. All models and serializers should have "user" instead of "author" to resolve this issue

* test(be): implement unit tests for rate_quiz

* fix(be): add try-except in permissions.py to handle both author and user fields

* refactor(be): remove commented parts in serializers

---------

Co-authored-by: Ceydanur Şen <[email protected]>
Co-authored-by: MucahitErdoganUnlu <[email protected]>
Co-authored-by: ozankrkya <[email protected]>
  • Loading branch information
4 people authored Nov 15, 2024
1 parent 981bd92 commit 7e21eee
Show file tree
Hide file tree
Showing 27 changed files with 796 additions and 20 deletions.
15 changes: 14 additions & 1 deletion backend/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,17 @@
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(days=7),
"REFRESH_TOKEN_LIFETIME": timedelta(days=14),
}
}

SWAGGER_SETTINGS = {
'USE_SESSION_AUTH': False,
'SECURITY_DEFINITIONS': {
'Bearer': {
'type': 'apiKey',
'in': 'header',
'name': 'Authorization',
'description': 'Use with "Bearer <YOUR_TOKEN_HERE>"',
}
},
}

7 changes: 7 additions & 0 deletions backend/core/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
from django.contrib import admin
from .models import CustomUser, ForumQuestion, Tag, Quiz, QuizQuestion, RateQuiz

# Register your models here.
admin.site.register(CustomUser)
admin.site.register(ForumQuestion)
admin.site.register(Tag)
admin.site.register(Quiz)
admin.site.register(QuizQuestion)
admin.site.register(RateQuiz)
File renamed without changes.
42 changes: 31 additions & 11 deletions backend/fixtures/data.json → backend/core/fixtures/data.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
[
{
"model": "core.customuser",
"pk": 1,
"fields": {
"username": "admin",
"email": "[email protected]",
"full_name": "admin",
"password": "group11admin"
}
},

{
"model": "core.customuser",
"pk": 2,
Expand Down Expand Up @@ -79,7 +70,36 @@
"question": "What do you think about the future of technology?",
"author": 2,
"tags": [1],
"created_at": "2021-11-01T00:00:00Z"
"created_at": "2024-11-01T00:00:00Z"
}
},
{
"model": "core.quiz",
"pk": 1,
"fields": {
"title": "Technology Quiz",
"description": "Test your knowledge about technology",
"author": 2,
"created_at": "2024-11-01T00:00:00Z",
"difficulty": 1,
"tags": [1],
"type": 1
}
},
{
"model": "core.quizquestion",
"pk": 1,
"fields": {
"question_text": "What is the definition of the word 'demure'?",
"choices": [
"shy, modest",
"loud, obnoxious",
"happy, joyful",
"sad, depressed"
],
"answer": "shy, modest",
"quiz": 1
}
}

]
38 changes: 38 additions & 0 deletions backend/core/migrations/0006_quiz_quizquestion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 5.1.2 on 2024-11-04 14:17

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0005_customuser_avatar'),
]

operations = [
migrations.CreateModel(
name='Quiz',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('description', models.TextField()),
('date', models.DateTimeField(auto_now_add=True)),
('proficiency_level', models.IntegerField(choices=[(1, 'Beginner'), (2, 'Intermediate'), (3, 'Advanced'), (4, 'Expert')])),
('quiz_type', models.IntegerField(choices=[(1, 'English to Turkish'), (2, 'Turkish to English'), (3, 'English word to Sense')])),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('tags', models.ManyToManyField(to='core.tag')),
],
),
migrations.CreateModel(
name='QuizQuestion',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('question_text', models.CharField(max_length=1000)),
('choices', models.JSONField()),
('correct_answer', models.CharField(max_length=255)),
('quiz', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='questions', to='core.quiz')),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 5.1.2 on 2024-11-09 18:30

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0006_quiz_quizquestion'),
]

operations = [
migrations.RenameField(
model_name='forumquestion',
old_name='date',
new_name='created_at',
),
migrations.RenameField(
model_name='quiz',
old_name='date',
new_name='created_at',
),
]
18 changes: 18 additions & 0 deletions backend/core/migrations/0008_rename_quiz_type_quiz_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.1.2 on 2024-11-09 18:36

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0007_rename_date_forumquestion_created_at_and_more'),
]

operations = [
migrations.RenameField(
model_name='quiz',
old_name='quiz_type',
new_name='type',
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.1.2 on 2024-11-09 18:40

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0008_rename_quiz_type_quiz_type'),
]

operations = [
migrations.RenameField(
model_name='quiz',
old_name='proficiency_level',
new_name='difficulty',
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.1.2 on 2024-11-09 21:27

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0009_rename_proficiency_level_quiz_difficulty'),
]

operations = [
migrations.RenameField(
model_name='quizquestion',
old_name='correct_answer',
new_name='answer',
),
]
25 changes: 25 additions & 0 deletions backend/core/migrations/0011_takequiz.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 5.1.2 on 2024-11-12 11:30

import django.core.validators
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0010_rename_correct_answer_quizquestion_answer'),
]

operations = [
migrations.CreateModel(
name='TakeQuiz',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('rating', models.IntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(5)])),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('quiz', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.quiz')),
],
),
]
18 changes: 18 additions & 0 deletions backend/core/migrations/0012_rename_author_takequiz_quiz_taker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.1.2 on 2024-11-12 11:31

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0011_takequiz'),
]

operations = [
migrations.RenameField(
model_name='takequiz',
old_name='author',
new_name='quiz_taker',
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.1.2 on 2024-11-12 12:55

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0012_rename_author_takequiz_quiz_taker'),
]

operations = [
migrations.RenameField(
model_name='takequiz',
old_name='quiz_taker',
new_name='quiz_taker_user',
),
]
22 changes: 22 additions & 0 deletions backend/core/migrations/0014_rename_takequiz_ratequiz_and_more.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.1.2 on 2024-11-14 16:30

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0013_rename_quiz_taker_takequiz_quiz_taker_user'),
]

operations = [
migrations.RenameModel(
old_name='TakeQuiz',
new_name='RateQuiz',
),
migrations.RenameField(
model_name='ratequiz',
old_name='quiz_taker_user',
new_name='quiz_rater_user',
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.1.2 on 2024-11-14 16:41

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0014_rename_takequiz_ratequiz_and_more'),
]

operations = [
migrations.RenameField(
model_name='ratequiz',
old_name='quiz_rater_user',
new_name='user',
),
]
17 changes: 17 additions & 0 deletions backend/core/migrations/0016_alter_ratequiz_unique_together.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.1.2 on 2024-11-14 16:59

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0015_rename_quiz_rater_user_ratequiz_user'),
]

operations = [
migrations.AlterUniqueTogether(
name='ratequiz',
unique_together={('quiz', 'user')},
),
]
17 changes: 17 additions & 0 deletions backend/core/migrations/0017_alter_ratequiz_unique_together.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.1.2 on 2024-11-14 16:59

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0016_alter_ratequiz_unique_together'),
]

operations = [
migrations.AlterUniqueTogether(
name='ratequiz',
unique_together=set(),
),
]
17 changes: 17 additions & 0 deletions backend/core/migrations/0018_alter_ratequiz_unique_together.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.1.2 on 2024-11-14 17:05

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0017_alter_ratequiz_unique_together'),
]

operations = [
migrations.AlterUniqueTogether(
name='ratequiz',
unique_together={('quiz', 'user')},
),
]
Loading

0 comments on commit 7e21eee

Please sign in to comment.