Skip to content

Commit

Permalink
Merge pull request #83 from PROCOLLAB-github/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
sh1nkey authored Jun 24, 2024
2 parents 0b9856b + e9a4086 commit 98809c2
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 4 deletions.
1 change: 1 addition & 0 deletions apps/courses/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class TaskObjectAdmin(admin.ModelAdmin):
"id",
"task_name",
"question_type",
"validate_answer",
"has_popups",
"ordinal_number",
)
Expand Down
18 changes: 18 additions & 0 deletions apps/courses/migrations/0010_taskobject_validate_answer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.3 on 2024-06-24 18:21

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("courses", "0009_task_status"),
]

operations = [
migrations.AddField(
model_name="taskobject",
name="validate_answer",
field=models.BooleanField(default=True, verbose_name="Проверять ответ на вопрос?"),
),
]
9 changes: 9 additions & 0 deletions apps/courses/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ class TaskObject(models.Model):
object_id = models.PositiveIntegerField(verbose_name="ID единицы задачи")
popup = models.ManyToManyField("Popup", blank=True, related_name="task_objects", verbose_name="Поп-ап")
content_object = GenericForeignKey("content_type", "object_id")
validate_answer = models.BooleanField(
default=True,
verbose_name="Проверка ответа",
help_text=(
"Отключает проверку ответа.<br>"
"(Только для 'Вопрос с одним правильным ответом', 'Вопрос с одним правильным ответом (Исключающий)' "
"и 'Вопрос на соотношение', на остальных проверка не требуется)"
),
)

def __str__(self):
return f"{self.task.name} {self.ordinal_number}"
Expand Down
25 changes: 25 additions & 0 deletions apps/questions/services.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from typing import Iterable, Optional

from rest_framework.response import Response
from rest_framework import status
from rest_framework.utils.serializer_helpers import ReturnDict

from questions.mapping import TypeQuestionPoints
from courses.models import TaskObject
from progress.models import TaskObjUserResult


def get_error_message_for_permissions(needed_model_class: str, gotten_model_class: str) -> dict[str: str]:
Expand Down Expand Up @@ -28,3 +34,22 @@ def add_popup_data(data: ReturnDict | dict, task_object: TaskObject) -> ReturnDi
"ordinal_number": popup.ordinal_number,
})
return data


def handle_no_validation_required(
task_object_id: int,
profile_id: int,
point_type: TypeQuestionPoints,
request_data: Iterable,
response_data: dict,
required_data: Optional[Iterable] = None,
) -> Response:
"""
Если у TaskObject отключена проверка.
Проверка лишь на наличие ответа, а в случае с вопросом на соотношение, что все блоки сопоставлены.
"""
if (required_data and len(request_data) < len(required_data)) or not request_data:
return Response({"text": "need more..."}, status=status.HTTP_400_BAD_REQUEST)

TaskObjUserResult.objects.create_user_result(task_object_id, profile_id, point_type)
return Response(response_data, status=status.HTTP_201_CREATED)
41 changes: 37 additions & 4 deletions apps/questions/views/answers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
from procollab_skills.permissions import IfSubscriptionOutdatedPermission
from progress.models import TaskObjUserResult

from questions import serializers
from questions import api_examples
from questions.exceptions import UserAlreadyAnsweredException
from questions.mapping import TypeQuestionPoints
from questions.permissions import CheckQuestionTypePermission, SimpleCheckQuestionTypePermission
from questions.services import handle_no_validation_required
from questions.models import (
QuestionSingleAnswer,
QuestionConnect,
Expand All @@ -19,8 +22,6 @@
AnswerSingle,
AnswerConnect,
)
from questions import serializers
from questions import api_examples


@extend_schema(
Expand All @@ -47,6 +48,17 @@ class SingleCorrectPost(generics.CreateAPIView):

def create(self, request, *args, **kwargs) -> Response:
try:

# Если у TaskObject отключена проверка ответа, то дальнешие действия не нужны.
if not self.request_task_object.validate_answer:
return handle_no_validation_required(
self.task_object_id,
self.profile_id,
TypeQuestionPoints.QUESTION_SINGLE_ANSWER,
request.data.get("answer_id"),
{"is_correct": True},
)

question_answers: QuerySet[AnswerSingle] = self.request_question.single_answers.all()
given_answer: AnswerSingle = question_answers.get(id=request.data.get("answer_id"))
is_correct_answer: bool = given_answer.is_correct
Expand Down Expand Up @@ -94,10 +106,21 @@ class ConnectQuestionPost(generics.CreateAPIView):

def create(self, request, *args, **kwargs) -> Response:
try:
user_answers = request.data

question: QuestionConnect = self.request_question
all_answer_options: QuerySet[AnswerConnect] = question.connect_answers.all()

# Если у TaskObject отключена проверка ответа, то дальнешие действия не нужны.
if not self.request_task_object.validate_answer:
return handle_no_validation_required(
self.task_object_id,
self.profile_id,
TypeQuestionPoints.QUESTION_CONNECT,
request.data,
{"text": "success"},
required_data=all_answer_options,
)

user_answers = request.data
answers_left_to_check: list[int] = list(all_answer_options.values_list("id", flat=True))
# all_answers_count = all_answer_options.count()

Expand Down Expand Up @@ -163,6 +186,16 @@ def create(self, request, *args, **kwargs) -> Response:
try:
given_answer_ids: list[int] = request.data

# Если у TaskObject отключена проверка ответа, то дальнешие действия не нужны.
if not self.request_task_object.validate_answer:
return handle_no_validation_required(
self.task_object_id,
self.profile_id,
TypeQuestionPoints.QUESTION_EXCLUDE,
given_answer_ids,
{"text": "success"},
)

# Все правильные ответы (в рамках исключения).
set_correct_answer_ids: set[int] = set(
self.request_question.single_answers.filter(is_correct=False).values_list("id", flat=True)
Expand Down

0 comments on commit 98809c2

Please sign in to comment.