feature/tests #18
@ -4,11 +4,13 @@ from answers.models import Answer
|
|||||||
|
|
||||||
|
|
||||||
class AnswerSerializer(serializers.ModelSerializer):
|
class AnswerSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Answer
|
model = Answer
|
||||||
fields = (
|
fields = (
|
||||||
"id",
|
"id",
|
||||||
"description",
|
"description",
|
||||||
"is_correct",
|
"is_correct",
|
||||||
"question"
|
# "question"
|
||||||
)
|
)
|
||||||
|
0
categories/__init__.py
Normal file
0
categories/__init__.py
Normal file
3
categories/admin.py
Normal file
3
categories/admin.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
6
categories/apps.py
Normal file
6
categories/apps.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class CategoriesConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'categories'
|
21
categories/migrations/0001_initial.py
Normal file
21
categories/migrations/0001_initial.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2021-12-11 22:36
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Category',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(default='', max_length=200)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
0
categories/migrations/__init__.py
Normal file
0
categories/migrations/__init__.py
Normal file
9
categories/models.py
Normal file
9
categories/models.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
|
|
||||||
|
|
||||||
|
class Category(models.Model):
|
||||||
|
name = models.CharField(max_length=200, default="")
|
||||||
|
|
||||||
|
|
13
categories/serializers.py
Normal file
13
categories/serializers.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from categories.models import Category
|
||||||
|
|
||||||
|
|
||||||
|
class CategorySerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Category
|
||||||
|
fields = (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
)
|
8
categories/urls.py
Normal file
8
categories/urls.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
|
from categories.views import CategoryModelViewSet
|
||||||
|
|
||||||
|
router = DefaultRouter()
|
||||||
|
router.register("items", CategoryModelViewSet)
|
||||||
|
|
||||||
|
urlpatterns = router.urls
|
9
categories/views.py
Normal file
9
categories/views.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from rest_framework import viewsets
|
||||||
|
|
||||||
|
from categories.models import Category
|
||||||
|
from categories.serializers import CategorySerializer
|
||||||
|
|
||||||
|
|
||||||
|
class CategoryModelViewSet(viewsets.ModelViewSet):
|
||||||
|
queryset = Category.objects.all()
|
||||||
|
serializer_class = CategorySerializer
|
@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
from datetime import timedelta
|
||||||
"""
|
"""
|
||||||
Django settings for config project.
|
Django settings for config project.
|
||||||
|
|
||||||
@ -56,7 +57,8 @@ INSTALLED_APPS = [
|
|||||||
"users",
|
"users",
|
||||||
"trials",
|
"trials",
|
||||||
"answers",
|
"answers",
|
||||||
"questions"
|
"questions",
|
||||||
|
"categories"
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@ -153,6 +155,12 @@ if not DEVELOPMENT:
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
SIMPLE_JWT = {
|
||||||
|
"AUTH_HEADER_TYPES": ("Bearer", ),
|
||||||
|
'ACCESS_TOKEN_LIFETIME': timedelta(days=365),
|
||||||
|
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
|
||||||
|
}
|
||||||
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||||
|
@ -27,4 +27,5 @@ urlpatterns = [
|
|||||||
path('questions/', include("questions.urls")),
|
path('questions/', include("questions.urls")),
|
||||||
path('answers/', include("answers.urls")),
|
path('answers/', include("answers.urls")),
|
||||||
path('tests/', include("trials.urls")),
|
path('tests/', include("trials.urls")),
|
||||||
|
path('categories/', include("categories.urls")),
|
||||||
]
|
]
|
||||||
|
27
questions/managers.py
Normal file
27
questions/managers.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
from django.db.models import Manager
|
||||||
|
from django.apps import apps
|
||||||
|
from django.conf import settings
|
||||||
|
from categories.models import Category
|
||||||
|
|
||||||
|
|
||||||
|
class QuestionManager(Manager):
|
||||||
|
def create(
|
||||||
|
self, *,
|
||||||
|
answers=[],
|
||||||
|
test=None,
|
||||||
|
description=None,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
Answer = apps.get_model("answers", "Answer")
|
||||||
|
instance = super().create(
|
||||||
|
test=test,
|
||||||
|
description=description,
|
||||||
|
)
|
||||||
|
for answer in answers:
|
||||||
|
Answer.objects.create(
|
||||||
|
question=instance,
|
||||||
|
description=answer["description"],
|
||||||
|
is_correct=answer["is_correct"]
|
||||||
|
)
|
||||||
|
return instance
|
||||||
|
|
18
questions/migrations/0003_alter_question_description.py
Normal file
18
questions/migrations/0003_alter_question_description.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2021-12-12 22:27
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('questions', '0002_question_points'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='question',
|
||||||
|
name='description',
|
||||||
|
field=models.CharField(max_length=200),
|
||||||
|
),
|
||||||
|
]
|
@ -1,4 +1,5 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
from .managers import QuestionManager
|
||||||
|
|
||||||
|
|
||||||
class Question(models.Model):
|
class Question(models.Model):
|
||||||
@ -9,7 +10,7 @@ class Question(models.Model):
|
|||||||
related_name="questions"
|
related_name="questions"
|
||||||
)
|
)
|
||||||
name = models.CharField(max_length=200, default="")
|
name = models.CharField(max_length=200, default="")
|
||||||
description = models.TextField()
|
description = models.CharField(max_length=200)
|
||||||
points = models.PositiveSmallIntegerField(default=1)
|
points = models.PositiveSmallIntegerField(default=1)
|
||||||
|
|
||||||
def get_answers_secret(self):
|
def get_answers_secret(self):
|
||||||
@ -17,3 +18,5 @@ class Question(models.Model):
|
|||||||
answer.get_secret_answer()
|
answer.get_secret_answer()
|
||||||
for answer in self.answers.all()
|
for answer in self.answers.all()
|
||||||
]
|
]
|
||||||
|
|
||||||
|
objects = QuestionManager()
|
@ -1,14 +1,17 @@
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from questions.models import Question
|
from questions.models import Question
|
||||||
|
from answers.serializers import AnswerSerializer
|
||||||
|
|
||||||
|
|
||||||
class QuestionSerializer(serializers.ModelSerializer):
|
class QuestionSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
answers = serializers.SerializerMethodField()
|
# answers = serializers.SerializerMethodField()
|
||||||
|
#
|
||||||
|
# def get_answers(self, instance: Question):
|
||||||
|
# return instance.get_answers_secret()
|
||||||
|
|
||||||
def get_answers(self, instance: Question):
|
answers = AnswerSerializer(many=True, required=False)
|
||||||
return instance.get_answers_secret()
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Question
|
model = Question
|
||||||
@ -19,3 +22,6 @@ class QuestionSerializer(serializers.ModelSerializer):
|
|||||||
"answers",
|
"answers",
|
||||||
"test"
|
"test"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
import pdb;pdb.set_trace()
|
||||||
|
@ -2,7 +2,7 @@ from rest_framework.routers import DefaultRouter
|
|||||||
|
|
||||||
from questions.views import QuestionModelViewSet
|
from questions.views import QuestionModelViewSet
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter(trailing_slash=False)
|
||||||
router.register("items", QuestionModelViewSet)
|
router.register("items", QuestionModelViewSet)
|
||||||
|
|
||||||
urlpatterns = router.urls
|
urlpatterns = router.urls
|
||||||
|
23
test.json
Normal file
23
test.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "asd",
|
||||||
|
"passing_score": 1,
|
||||||
|
"questions": [
|
||||||
|
{
|
||||||
|
"name": "heja",
|
||||||
|
"description": "czesc",
|
||||||
|
"answers": [
|
||||||
|
{
|
||||||
|
"description": "hejka_answer",
|
||||||
|
"is_correct": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "hejka2_answer",
|
||||||
|
"is_correct": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"category": {
|
||||||
|
"name": "Polski"
|
||||||
|
}
|
||||||
|
}
|
42
trials/managers.py
Normal file
42
trials/managers.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
from django.db.models import Manager
|
||||||
|
from django.apps import apps
|
||||||
|
from django.conf import settings
|
||||||
|
from categories.models import Category
|
||||||
|
|
||||||
|
|
||||||
|
class TestManager(Manager):
|
||||||
|
|
||||||
|
def create(
|
||||||
|
self, *,
|
||||||
|
category=None,
|
||||||
|
questions=[],
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
Question = apps.get_model("questions", "Question")
|
||||||
|
Answer = apps.get_model("answers", "Answer")
|
||||||
|
category = Category.objects.get_or_create(
|
||||||
|
name=category["name"]
|
||||||
|
)
|
||||||
|
|
||||||
|
instance = super().create(
|
||||||
|
name=kwargs.get("name"),
|
||||||
|
passing_score=kwargs.get("passing_score"),
|
||||||
|
category=category[0]
|
||||||
|
)
|
||||||
|
# import pdb;pdb.set_trace()
|
||||||
|
for question in questions:
|
||||||
|
question_instance = Question.objects.create(
|
||||||
|
name=question["name"],
|
||||||
|
description=question["description"],
|
||||||
|
test=instance
|
||||||
|
)
|
||||||
|
for answer in question["answers"]:
|
||||||
|
import pdb;
|
||||||
|
pdb.set_trace()
|
||||||
|
Answer.objects.create(
|
||||||
|
description=answer["description"],
|
||||||
|
is_correct=answer["is_correct"],
|
||||||
|
question=question_instance
|
||||||
|
)
|
||||||
|
|
||||||
|
return instance
|
18
trials/migrations/0003_test_category.py
Normal file
18
trials/migrations/0003_test_category.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2021-12-11 22:03
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('trials', '0002_test_passing_score'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='test',
|
||||||
|
name='category',
|
||||||
|
field=models.CharField(default='', max_length=100),
|
||||||
|
),
|
||||||
|
]
|
17
trials/migrations/0004_remove_test_category.py
Normal file
17
trials/migrations/0004_remove_test_category.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2021-12-11 22:17
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('trials', '0003_test_category'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='test',
|
||||||
|
name='category',
|
||||||
|
),
|
||||||
|
]
|
20
trials/migrations/0005_test_category.py
Normal file
20
trials/migrations/0005_test_category.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2021-12-11 22:36
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('categories', '0001_initial'),
|
||||||
|
('trials', '0004_remove_test_category'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='test',
|
||||||
|
name='category',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tests', to='categories.category'),
|
||||||
|
),
|
||||||
|
]
|
@ -1,9 +1,18 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
from .managers import TestManager
|
||||||
|
|
||||||
|
|
||||||
class Test(models.Model):
|
class Test(models.Model):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
passing_score = models.PositiveSmallIntegerField(default=0)
|
passing_score = models.PositiveSmallIntegerField(default=0)
|
||||||
|
category = models.ForeignKey(
|
||||||
|
"categories.Category",
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
null=True,
|
||||||
|
related_name="tests"
|
||||||
|
)
|
||||||
|
|
||||||
|
objects = TestManager()
|
||||||
|
|
||||||
def get_score(self, answers):
|
def get_score(self, answers):
|
||||||
"""
|
"""
|
||||||
|
@ -2,11 +2,13 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
from questions.serializers import QuestionSerializer
|
from questions.serializers import QuestionSerializer
|
||||||
from trials.models import Test
|
from trials.models import Test
|
||||||
|
from categories.serializers import CategorySerializer
|
||||||
|
|
||||||
|
|
||||||
class TestSerializer(serializers.ModelSerializer):
|
class TestSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
questions = QuestionSerializer(many=True, required=False)
|
questions = QuestionSerializer(many=True, required=False)
|
||||||
|
category = CategorySerializer(required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Test
|
model = Test
|
||||||
@ -14,5 +16,13 @@ class TestSerializer(serializers.ModelSerializer):
|
|||||||
"id",
|
"id",
|
||||||
"name",
|
"name",
|
||||||
"passing_score",
|
"passing_score",
|
||||||
"questions"
|
"questions",
|
||||||
|
"category",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
instance = Test.objects.create(
|
||||||
|
**validated_data
|
||||||
|
)
|
||||||
|
return instance
|
||||||
|
|
||||||
|
@ -5,12 +5,12 @@ from trials.views import TestModelViewSet
|
|||||||
from trials.views import TestTemplateView
|
from trials.views import TestTemplateView
|
||||||
from trials.views import TestValidateAPIView
|
from trials.views import TestValidateAPIView
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter(trailing_slash=False)
|
||||||
router.register("items", TestModelViewSet)
|
router.register("items", TestModelViewSet)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('<int:test_id>/show/', TestTemplateView.as_view()),
|
path('<int:test_id>/show', TestTemplateView.as_view()),
|
||||||
path('<int:test_id>/mark/', TestValidateAPIView.as_view())
|
path('<int:test_id>/mark', TestValidateAPIView.as_view())
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns += router.urls
|
urlpatterns += router.urls
|
||||||
|
Loading…
Reference in New Issue
Block a user