Skip to content
Snippets Groups Projects
Commit 7f84cc58 authored by borzechof99's avatar borzechof99 :whale2:
Browse files

Implement Question API (and remove PK-attribute of Question-Criteria connection)

parent e61e6e3a
No related branches found
No related tags found
No related merge requests found
# Generated by Django 3.2 on 2021-06-27 21:40
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('quiz', '0008_auto_20210627_1812'),
]
operations = [
migrations.AddField(
model_name='question',
name='id',
field=models.BigAutoField(auto_created=True, default=1, primary_key=True, serialize=False, verbose_name='ID'),
preserve_default=False,
),
migrations.AlterField(
model_name='question',
name='criterion',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='quiz.criterion'),
),
]
......@@ -142,7 +142,10 @@ class Criterion(models.Model):
rating_sum = 0
for rating_obj in CriterionRating.objects.filter(criterion=self):
rating_sum += rating_obj.rating
if rating_obj.rating != -1:
rating_sum += rating_obj.rating
if rating_obj.rating > 1:
num_active += 1
......@@ -169,13 +172,25 @@ class KnowledgeSnack(models.Model):
return self.text
class QuestionManager(models.Manager):
"""
Manages Deletion of Question Objects and their Criteria
"""
def delete_question(self, pk):
question = self.get(pk=pk)
question.criterion.delete()
question.delete()
class Question(models.Model):
"""Defines a Question that is assigned to exactly one Criterion"""
text = models.TextField()
criterion = models.OneToOneField(
Criterion, on_delete=models.CASCADE, primary_key=True
)
criterion = models.OneToOneField(Criterion, on_delete=models.CASCADE)
objects = QuestionManager()
def __str__(self):
return self.text
......
......@@ -217,3 +217,36 @@ class SmallQuestionListSerializer(serializers.BaseSerializer):
)
return question_list
class SingleQuestionSerializer(serializers.BaseSerializer):
def to_representation(self, question):
number_of_sports_active, sum_of_weights = question.criterion.get_active_sum()
question_dict = {
"id": question.pk,
"text_de": question.text_de,
"text_en": question.text_en,
"criterion": question.criterion.name,
"number_of_sports_active": number_of_sports_active,
"sum_of_weights": sum_of_weights,
}
return question_dict
def to_internal_value(self, data):
validated_data = {}
# Test if Values exist
if "text_de" in data.keys():
validated_data["text_de"] = data["text_de"]
if "text_en" in data.keys():
validated_data["text_en"] = data["text_en"]
if "criterion" in data.keys():
validated_data["criterion"] = data["criterion"]
return validated_data
......@@ -11,6 +11,7 @@ from django.http import HttpResponse
from .pagination import PageNumberWithPageSizePagination
from .serializers import (
SingleQuestionSerializer,
SmallSportListSerializer,
SportListSerializer,
CriterionListSerializer,
......@@ -20,7 +21,7 @@ from .serializers import (
IncompleteSportSerializer,
SmallQuestionListSerializer,
)
from .models import Sport, Criterion, Question
from .models import Sport, Criterion, Question, QuestionOrderEntry
from .pagination import PageNumberWithPageSizePagination
# Create your views here.
......@@ -291,3 +292,136 @@ class SmallQuestionListView(viewsets.ViewSet):
api/admin/question POST
Takes Values of a new Question and Creates a Question and its corresponding Criterion
"""
new_question_data = SingleQuestionSerializer().to_internal_value(request.data)
if not (
"text_de" in new_question_data.keys()
and "criterion" in new_question_data.keys()
):
return Response(status=400)
# Test if the Criterion already exists
queryset = Criterion.objects.filter(name=new_question_data["criterion"])
if queryset.count() > 0:
return Response(
data={
"error": f"Criterion with name {new_question_data['criterion']} already exists"
},
status=400,
)
# Otherwise, all is well and we can create them
new_question = Question()
new_question.text_de = new_question_data["text_de"]
if "text_en" in new_question_data.keys():
new_question.text_en = new_question_data["text_en"]
new_criterion = Criterion.objects.create_criterion()
new_criterion.name = new_question_data["criterion"]
new_question.criterion = new_criterion
new_question.save()
new_criterion.save()
return Response(SingleQuestionSerializer(new_question).data)
def retrieve(self, request, pk=None):
"""
api/admin/question/id GET
Retrieves the Question object given the PK in the URL
"""
question = get_object_or_404(Question, pk=pk)
return Response(SingleQuestionSerializer(question).data)
def update(self, request, pk=None):
"""
api/admin/question/id PUT
Completely updates a Question Object given the PK in the URL
"""
new_question_data = SingleQuestionSerializer().to_internal_value(request.data)
question = get_object_or_404(Question, pk=pk)
try:
# Check if another Criterion with the wanted name already exists
queryset = Criterion.objects.filter(
name=new_question_data["criterion"]
).exclude(pk=question.criterion.pk)
if queryset.count() > 0:
return Response(
data={
"error": f"Criterion with name {new_question_data['criterion']} already exists"
},
status=400,
)
question.criterion.name = new_question_data["criterion"]
question.text_de = new_question_data["text_de"]
question.text_en = new_question_data["text_en"]
except:
return Response(status=400)
question.save()
question.criterion.save()
return Response(SingleQuestionSerializer(question).data)
def partial_update(self, request, pk=None):
"""
api/admin/question/id PATCH
Updates a Question Object with given values given the PK in the URL
"""
new_question_data = SingleQuestionSerializer().to_internal_value(request.data)
question = get_object_or_404(Question, pk=pk)
if "criterion" in new_question_data.keys():
# Check if another Criterion with the wanted name already exists
queryset = Criterion.objects.filter(
name=new_question_data["criterion"]
).exclude(pk=question.criterion.pk)
if queryset.count() > 0:
return Response(
data={
"error": f"Criterion with name {new_question_data['criterion']} already exists"
},
status=400,
)
question.criterion.name = new_question_data["criterion"]
if "text_de" in new_question_data.keys():
question.text_de = new_question_data["text_de"]
if "text_en" in new_question_data.keys():
question.text_en = new_question_data["text_en"]
question.save()
question.criterion.save()
return Response(SingleQuestionSerializer(question).data)
def destroy(self, request, pk=None):
"""
api/admin/question/id DELETE
Deletes the Question given by the ID in the URL and removes it from the QuestionOrderEntry-DB
"""
question = get_object_or_404(Question, pk=pk)
QuestionOrderEntry.objects.delete_entry_by_question_id(question.pk)
Question.objects.delete_question(question.pk)
return Response(status=404)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment