From 9867281dd82a0509b18aa3823cda1f9200e0cfe1 Mon Sep 17 00:00:00 2001 From: Hubert Jankowski Date: Wed, 25 May 2022 00:06:44 +0200 Subject: [PATCH] Add tournaments --- templates/createTournament.html | 14 ++- templates/generic_tournament.html | 54 +++++++++ templates/tournament_result.html | 56 +++++++++ templates/tournaments.html | 6 +- trials/managers.py | 21 ++++ .../0024_alter_tournament_password.py | 18 +++ .../0025_tournament_passing_score.py | 18 +++ .../migrations/0026_tournament_completions.py | 18 +++ trials/migrations/0027_auto_20220524_2354.py | 43 +++++++ trials/models.py | 70 +++++++++++- trials/urls.py | 6 +- trials/views.py | 107 +++++++++++++++++- 12 files changed, 418 insertions(+), 13 deletions(-) create mode 100644 templates/generic_tournament.html create mode 100644 templates/tournament_result.html create mode 100644 trials/migrations/0024_alter_tournament_password.py create mode 100644 trials/migrations/0025_tournament_passing_score.py create mode 100644 trials/migrations/0026_tournament_completions.py create mode 100644 trials/migrations/0027_auto_20220524_2354.py diff --git a/templates/createTournament.html b/templates/createTournament.html index 8b531a7..175fe2f 100644 --- a/templates/createTournament.html +++ b/templates/createTournament.html @@ -1,14 +1,19 @@ {% extends "base.html" %} +{% load rest_framework %} {% block title %}Stwórz turniej{% endblock %} {% block content %}

Stwórz turniej

+ name:
+ passing score: {% for question in questions %} +
- + + {{ question.description }}
@@ -20,9 +25,10 @@
{% endfor %}
-
-
- +
+
+ + {% endblock %} diff --git a/templates/generic_tournament.html b/templates/generic_tournament.html new file mode 100644 index 0000000..016bbf6 --- /dev/null +++ b/templates/generic_tournament.html @@ -0,0 +1,54 @@ +{% extends "base.html" %} +{% load rest_framework %} + +{% block title %}{{ test.name }}{% endblock %} + +{% block additional_head %} + + + +{% endblock %} + +{% block content %} +
+
+
+ {{ tournament.name }} +
+
+ {% for question in questions %} +
+ {{ question.description }} +
+
+ {% for answer in question.answers.all %} + + {% endfor %} +
+ {% endfor %} +
+ +
+
+
+ +
+ +{% endblock %} + diff --git a/templates/tournament_result.html b/templates/tournament_result.html new file mode 100644 index 0000000..80b072c --- /dev/null +++ b/templates/tournament_result.html @@ -0,0 +1,56 @@ +{% extends "base.html" %} +{% load social_share %} + +{% block title %}Test result{% endblock %} + +{% block content %} +
+ Card image cap +
+
+ + {% if request.session.percentage == 100 %} + Idealnie, widzę że ten temat nie ma dla ciebie tajemnic! + {% elif request.session.percentage >= 75 %} + Bardzo dobrze, ale są jeszcze pewne braki ;) + {% elif request.session.percentage >= 50 %} + Nie jest źle, wiedziałeś więcej niż mniej + {% elif request.session.percentage >= 25 %} + Masz spore braki, powinieneś trochę więcej się pouczyć + {% else %} + Słabiutko, ale następnym razem będzie lepiej + {% endif %} +
+
Rezultat: {{ request.session.status }}
+
Twój wynik: {{ request.session.points }}
+
Próg zaliczenia: {{ request.session.passing }}
+
Maksymalny wynik: {{ request.session.max }}
+
Wynik procentowy: {{ request.session.percentage }}%
+ +

+ + + +

+ + {% if request.session.password == "" %} +
Udostępnij:
+ {% post_to_facebook object_or_url %} + {% post_to_linkedin object_or_url %} + {% endif %} + +

+ +
+
+ +{% endblock %} + diff --git a/templates/tournaments.html b/templates/tournaments.html index dd7f7d2..242674d 100644 --- a/templates/tournaments.html +++ b/templates/tournaments.html @@ -3,8 +3,8 @@ {% block title %}Turnieje{% endblock %} {% block content %} -

Twoje testy

- {% for test in tests %} +

Turnieje

+ {% for tournament in tournaments %}
{{tournament.name}} @@ -15,7 +15,7 @@ - +

{% endfor %} diff --git a/trials/managers.py b/trials/managers.py index 97ac3de..ca4103d 100644 --- a/trials/managers.py +++ b/trials/managers.py @@ -38,3 +38,24 @@ class TestManager(Manager): ) return instance + + +class TournamentManager(Manager): + + def create( + self, *, + name="", + questions=[], + passing_score=0, + **kwargs + ): + Question = apps.get_model("questions", "Question") + + instance = super().create( + name=name, + passing_score=passing_score + ) + for q in questions: + qq = Question.objects.get(id=q) + qq.tournament.add(instance.id) + return instance diff --git a/trials/migrations/0024_alter_tournament_password.py b/trials/migrations/0024_alter_tournament_password.py new file mode 100644 index 0000000..3b7340a --- /dev/null +++ b/trials/migrations/0024_alter_tournament_password.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2022-05-24 20:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('trials', '0023_tournament'), + ] + + operations = [ + migrations.AlterField( + model_name='tournament', + name='password', + field=models.CharField(default='', max_length=100), + ), + ] diff --git a/trials/migrations/0025_tournament_passing_score.py b/trials/migrations/0025_tournament_passing_score.py new file mode 100644 index 0000000..1b17fd2 --- /dev/null +++ b/trials/migrations/0025_tournament_passing_score.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2022-05-24 21:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('trials', '0024_alter_tournament_password'), + ] + + operations = [ + migrations.AddField( + model_name='tournament', + name='passing_score', + field=models.PositiveSmallIntegerField(default=0), + ), + ] diff --git a/trials/migrations/0026_tournament_completions.py b/trials/migrations/0026_tournament_completions.py new file mode 100644 index 0000000..dc5af53 --- /dev/null +++ b/trials/migrations/0026_tournament_completions.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2022-05-24 21:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('trials', '0025_tournament_passing_score'), + ] + + operations = [ + migrations.AddField( + model_name='tournament', + name='completions', + field=models.IntegerField(default=0), + ), + ] diff --git a/trials/migrations/0027_auto_20220524_2354.py b/trials/migrations/0027_auto_20220524_2354.py new file mode 100644 index 0000000..4062c42 --- /dev/null +++ b/trials/migrations/0027_auto_20220524_2354.py @@ -0,0 +1,43 @@ +# Generated by Django 3.2.9 on 2022-05-24 21:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('trials', '0026_tournament_completions'), + ] + + operations = [ + migrations.AddField( + model_name='tournament', + name='avg_difficulty', + field=models.FloatField(default=0.0), + ), + migrations.AddField( + model_name='tournament', + name='avg_rating', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='tournament', + name='difficulty_label', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='tournament', + name='rates_amount', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='tournament', + name='total_percentage_scored_by_users', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='tournament', + name='total_rating', + field=models.IntegerField(default=0), + ), + ] diff --git a/trials/models.py b/trials/models.py index 9894eb1..5349b02 100644 --- a/trials/models.py +++ b/trials/models.py @@ -2,7 +2,7 @@ from django.db import models from questions.models import Question from users.models import User -from .managers import TestManager +from .managers import TestManager, TournamentManager class Test(models.Model): @@ -114,4 +114,70 @@ class Tournament(models.Model): related_name="tournaments", on_delete=models.CASCADE ) - password = models.CharField(max_length=100) + password = models.CharField(max_length=100, default="") + passing_score = models.PositiveSmallIntegerField(default=0) + completions = models.IntegerField(default=0) + total_percentage_scored_by_users = models.IntegerField(default=0) + total_rating = models.IntegerField(default=0) + avg_rating = models.IntegerField(default=0) + rates_amount = models.IntegerField(default=0) + difficulty_label = models.IntegerField(default=0) + avg_difficulty = models.FloatField(default=0.0) + + objects = TournamentManager() + + + def get_score(self, answers): + """ + [ + { + "question": 1, + "answer": 1 + }, + { + "question": 2, + "answer": 1 + } + ] + """ + points = 0 + for answer in answers: + question = Question.objects.filter(tournament=self.id).get(id=answer["question"]) + if question.answers.get(id=answer["answer"]).is_correct: + points += question.points + return points + + def get_maxscore(self): + """ + [ + { + "question": 1, + "answer": 1 + }, + { + "question": 2, + "answer": 1 + } + ] + """ + points = 0 + for question in Question.objects.filter(tournament=self.id): + points += question.points + return points + + def question_count(self): + return Question.objects.filter(tournament=self.id).count() + + def get_author_name(self): + if self.created_by: + user = User.objects.get(email=self.created_by) + user_fullname = user.first_name + " " + user.last_name + else: + user_fullname = "SOITA" + return user_fullname + + def name_and_passing_score(self): + return { + "name": self.name, + "passing_score": self.passing_score + } diff --git a/trials/urls.py b/trials/urls.py index 9a8453f..fe2b64c 100644 --- a/trials/urls.py +++ b/trials/urls.py @@ -1,7 +1,7 @@ from django.urls import path from rest_framework.routers import DefaultRouter -from trials.views import TestModelViewSet, TestTemplateView, TestValidateAPIView, TestResultView, rateTest, addTest, addQuestions, myTests, solvedTests, solvedTestsDetailed, EditTestTemplateView, deleteTest, AddQuestionToExistingTest, RemoveQuestionFromExistingTest, EditQuestionTemplateView, editName, editVisible, editPassword, TestPasswordTemplateView, TournamentView, CreateTournamentView +from trials.views import TestModelViewSet, TestTemplateView, TestValidateAPIView, TestResultView, rateTest, addTest, addQuestions, myTests, solvedTests, solvedTestsDetailed, EditTestTemplateView, deleteTest, AddQuestionToExistingTest, RemoveQuestionFromExistingTest, EditQuestionTemplateView, editName, editVisible, editPassword, TestPasswordTemplateView, TournamentView, CreateTournamentView, TournamentTemplateView, TournamentResultView router = DefaultRouter(trailing_slash=False) router.register("items", TestModelViewSet) @@ -26,7 +26,9 @@ urlpatterns = [ path('solved', solvedTests, name="solvedTests"), path('solved/', solvedTestsDetailed, name="solvedTests"), path('tournamets', TournamentView, name="tournaments"), - path('add/tournament', CreateTournamentView, name="CreateTournament") + path('add/tournament', CreateTournamentView, name="CreateTournament"), + path('/tournament/show', TournamentTemplateView.as_view()), + path('/tournament/result', TournamentResultView.as_view()) ] urlpatterns += router.urls diff --git a/trials/views.py b/trials/views.py index 263c9fa..6362535 100644 --- a/trials/views.py +++ b/trials/views.py @@ -85,14 +85,28 @@ def addQuestions(request, **kwargs): def TournamentView(request): context = {} - context['tournament'] = Tournament.objects.all() + context['tournaments'] = Tournament.objects.all() return render(request, 'tournaments.html', context) -def CreateTournamentView(request): +def CreateTournamentView(request, **kwargs): + if request.POST: + question_ids = [] + dictt = dict(request.POST) + pyk = dictt.pop("name") + pyk2 = dictt.pop("passing_score") + name = request.POST.get("name") + passing_score = request.POST.get("passing_score") + for k, v in dictt.items(): + question_ids.append(k) + Tournament.objects.create(name=name, questions=question_ids, passing_score=passing_score) + return render(request, 'home.html') context = {} context['questions'] = Question.objects.all() return render(request, 'createTournament.html', context) + + + class AddQuestionToExistingTest(TemplateView): template_name = settings.BASE_DIR + f"/templates/addQuestionToExistingTest.html" @@ -411,6 +425,91 @@ class TestTemplateView(TemplateView): return HttpResponseRedirect(f'result') +class TournamentTemplateView(TemplateView): + PASSED = "Zaliczony" + FAILED = "Niezaliczony" + UNKNOWN = "nieznany" + + PASSED = { + True: PASSED, + False: FAILED + } + + permission_classes = [] + template_name = settings.BASE_DIR + f"/templates/generic_tournament.html" + test_id = None + + def get_queryset(self): + return Tournament.objects.all() + + def get_context_data(self, tournament_id, **kwargs): + self.test_id = tournament_id + context = super().get_context_data(**kwargs) + context["tournament"] = self.get_queryset().filter(id=tournament_id) + context["questions"] = Question.objects.filter(tournament=tournament_id) + return context + + def get_score(self, tournament: Tournament, answers): + return tournament.get_score(answers) + + def get_maxscore(self, tournament: Tournament): + return tournament.get_maxscore() + + def formatted_responses(self, unformatted_json): + formatted_response = list() + for question, answer in unformatted_json.items(): + formatted_response.append( + { + "question": question, + "answer": answer + } + ) + return formatted_response + + def post(self, request, *args, **kwargs): + tournament = Tournament.objects.get(id=kwargs.get("tournament_id")) + score = self.get_score(tournament, self.formatted_responses(request.POST)) + max = self.get_maxscore(tournament) + status = score >= tournament.passing_score + # context = { + # "status": self.PASSED.get(status, self.UNKNOWN), + # "points": score, + # "max": max, + # "passing": test.passing_score, + # "percentage": int(score / max * 100), + # "password": test.password + # } + request.session["status"] = self.PASSED.get(status, self.UNKNOWN) + request.session["points"] = score + request.session["max"] = max + request.session["passing"] = tournament.passing_score + request.session["percentage"] = int(score / max * 100) + request.session["password"] = tournament.password + # SolvedTest.objects.create( + # score=score, + # max=max, + # percentage=int(score / max * 100), + # user=request.user, + # test=test + # ) + tournament.completions += 1 + tournament.total_percentage_scored_by_users += int(score / max * 100) + if tournament.completions >= 5: + tournament.avg_difficulty = float(tournament.total_percentage_scored_by_users) / float(tournament.completions) + if tournament.avg_difficulty > 90.0: + tournament.difficulty_label = 1 + elif tournament.avg_difficulty > 75.0: + tournament.difficulty_label = 2 + elif tournament.avg_difficulty > 50.0: + tournament.difficulty_label = 3 + elif tournament.avg_difficulty > 25.0: + tournament.difficulty_label = 4 + else: + tournament.difficulty_label = 5 + tournament.save() + return HttpResponseRedirect(f'result') + + @login_required def TestPasswordTemplateView(request, test_id): test = Test.objects.get(id=test_id) @@ -471,3 +570,7 @@ class TestValidateAPIView(views.APIView): class TestResultView(TemplateView): permission_classes = [] template_name = settings.BASE_DIR + f"/templates/result.html" + +class TournamentResultView(TemplateView): + permission_classes = [] + template_name = settings.BASE_DIR + f"/templates/tournament_result.html" -- 2.20.1