From a0e0ff7e03e90a21cb429cb7290019c1a3f0161f Mon Sep 17 00:00:00 2001 From: Piotr Kopycki Date: Fri, 15 Apr 2022 16:59:14 +0200 Subject: [PATCH 01/12] Fixed the error of saving the test result after each page refresh --- templates/result.html | 20 ++++++++++---------- trials/views.py | 26 +++++++++++++++----------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/templates/result.html b/templates/result.html index afb7102..cc9d086 100644 --- a/templates/result.html +++ b/templates/result.html @@ -9,25 +9,25 @@
- {% if percentage == 100 %} + {% if request.session.percentage == 100 %} Idealnie, widzę że ten temat nie ma dla ciebie tajemnic! - {% elif percentage >= 75 %} + {% elif request.session.percentage >= 75 %} Bardzo dobrze, ale są jeszcze pewne braki ;) - {% elif percentage >= 50 %} + {% elif request.session.percentage >= 50 %} Nie jest źle, wiedziałeś więcej niż mniej - {% elif percentage >= 25 %} + {% 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: {{ status }}
-
Twój wynik: {{ points }}
-
Próg zaliczenia: {{ passing }}
-
Maksymalny wynik: {{ max }}
-
Wynik procentowy: {{ percentage }}%
+
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 password == "" %} + {% if request.session.password == "" %}
Udostępnij:
{% post_to_facebook object_or_url %} diff --git a/trials/views.py b/trials/views.py index a799360..71b0c83 100644 --- a/trials/views.py +++ b/trials/views.py @@ -336,14 +336,20 @@ class TestTemplateView(TemplateView): score = self.get_score(test, self.formatted_responses(request.POST)) max = self.get_maxscore(test, self.formatted_responses(request.POST)) status = score >= test.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 - } + # 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"] = test.passing_score + request.session["percentage"] = int(score / max * 100) + request.session["password"] = test.password SolvedTest.objects.create( score=score, max=max, @@ -351,9 +357,7 @@ class TestTemplateView(TemplateView): user=request.user, test=test ) - template_name = "result.html" - template = get_template(template_name) - return HttpResponse(template.render(context, request)) + return HttpResponseRedirect(f'result') def TestPasswordTemplateView(request, test_id): -- 2.20.1 From 696a573b080ea39ac7cd8ea65956ae30a7f8d48f Mon Sep 17 00:00:00 2001 From: Piotr Kopycki Date: Fri, 15 Apr 2022 21:04:04 +0200 Subject: [PATCH 02/12] Solved tests history upgrade --- palette.txt | 5 ++- static/style.css | 11 +++++- templates/changeEmail.html | 2 +- templates/solvedTests.html | 27 ++++++++------ templates/solvedTestsDetailed.html | 16 +++++++++ trials/urls.py | 9 ++--- trials/views.py | 57 +++++++++++++++++++----------- 7 files changed, 86 insertions(+), 41 deletions(-) create mode 100644 templates/solvedTestsDetailed.html diff --git a/palette.txt b/palette.txt index b1b3199..634cc57 100644 --- a/palette.txt +++ b/palette.txt @@ -1,8 +1,11 @@ Color palette: -#00916E - Illuminating Emerald #FEEFE5 - Linen #FFCF00 - Cyber Yellow #EE6123 - Orange Panteon #FA003F - Red Munsell +Buttons and links +#00916E - Illuminating Emerald + +Main color: #FF0B7E - Winter Sky \ No newline at end of file diff --git a/static/style.css b/static/style.css index ba70f33..338666a 100644 --- a/static/style.css +++ b/static/style.css @@ -97,7 +97,15 @@ border-radius: 25px; border: 2px solid #FF0B7E; padding: 20px; - width: 300px; + width: 320px; + height: 250px; +} + +.solvedTestContainerMini { + border-radius: 25px; + border: 2px solid #FF0B7E; + padding: 20px; + width: 320px; height: 200px; } @@ -453,6 +461,7 @@ background-color:#FF0B7E .linkDefault a { color: #00916E; text-decoration: none; + font-weight: bold; } .newContainer input[type=submit]{ diff --git a/templates/changeEmail.html b/templates/changeEmail.html index b9b70a9..23d805c 100644 --- a/templates/changeEmail.html +++ b/templates/changeEmail.html @@ -9,7 +9,7 @@

{% endblock %} diff --git a/templates/solvedTests.html b/templates/solvedTests.html index 8d958b6..262e6ef 100644 --- a/templates/solvedTests.html +++ b/templates/solvedTests.html @@ -4,16 +4,21 @@ {% block content %}

Historia rozwiązanych testów

- {% for test in tests %} -
-
- {{test.name}} + {% for test, results in tests_lists.items %} +
+
+ {{results.0.name}} +
+
Twój wynik: {{results.0.score}}
+
Próg zaliczenia: {{results.0.passing_score}}
+
Maksymalny wynik: {{results.0.max}}
+
Wynik procentowy: {{results.0.percentage}}%
+ {% if results|length > 1 %} + + {% endif %}
-
Twój wynik: {{test.score}}
-
Próg zaliczenia: {{test.passing_score}}
-
Maksymalny wynik: {{test.max}}
-
Wynik procentowy: {{test.percentage}}%
-
-
- {% endfor %} +
+ {% endfor %} {% endblock %} \ No newline at end of file diff --git a/templates/solvedTestsDetailed.html b/templates/solvedTestsDetailed.html new file mode 100644 index 0000000..dbeacb7 --- /dev/null +++ b/templates/solvedTestsDetailed.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} + +{% block title %}Historia testu{% endblock %} + +{% block content %} +

Historia testu: {{name}}

+ {% for test in tests %} +
+
Twój wynik: {{test.score}}
+
Próg zaliczenia: {{test.passing_score}}
+
Maksymalny wynik: {{test.max}}
+
Wynik procentowy: {{test.percentage}}%
+
+
+ {% endfor %} +{% endblock %} \ No newline at end of file diff --git a/trials/urls.py b/trials/urls.py index 44688db..fab316a 100644 --- a/trials/urls.py +++ b/trials/urls.py @@ -1,10 +1,7 @@ from django.urls import path from rest_framework.routers import DefaultRouter -from trials.views import TestModelViewSet -from trials.views import TestTemplateView -from trials.views import TestValidateAPIView -from trials.views import TestResultView, addTest, addQuestions, myTests, editTest, solvedTests, EditTestTemplateView, deleteTest, AddQuestionToExistingTest, RemoveQuestionFromExistingTest, EditQuestionTemplateView, editName, editVisible, editPassword, TestPasswordTemplateView +from trials.views import TestModelViewSet, TestTemplateView, TestValidateAPIView, TestResultView, addTest, addQuestions, myTests, solvedTests, solvedTestsDetailed, EditTestTemplateView, deleteTest, AddQuestionToExistingTest, RemoveQuestionFromExistingTest, EditQuestionTemplateView, editName, editVisible, editPassword, TestPasswordTemplateView router = DefaultRouter(trailing_slash=False) router.register("items", TestModelViewSet) @@ -22,11 +19,11 @@ urlpatterns = [ path('/editVisible', editVisible, name="editVisible"), path('/editPassword', editPassword, name="editPassword"), path('/remove', deleteTest, name="deleteTest"), - # path('delete', deleteTest, name="deleteTest"), path('add/test', addTest, name="newTest"), path('add/questions', addQuestions, name="addQuestions"), path('my', myTests, name="myTests"), - path('solved', solvedTests, name="solvedTests") + path('solved', solvedTests, name="solvedTests"), + path('solved/', solvedTestsDetailed, name="solvedTests") ] urlpatterns += router.urls diff --git a/trials/views.py b/trials/views.py index 71b0c83..4781553 100644 --- a/trials/views.py +++ b/trials/views.py @@ -156,31 +156,46 @@ def solvedTests(request): context = {} user_id = request.user.id solved_tests = SolvedTest.objects.filter(user__id=user_id) - formatted_tests = list() + dict_with_lists_of_test_results = {} for solved_test in solved_tests: - formatted_tests.append({ - "name": solved_test.test.name_and_passing_score()["name"], - "passing_score": solved_test.test.name_and_passing_score()["passing_score"], - "score": solved_test.score, - "max": solved_test.max, - "percentage": solved_test.percentage - }) - context['tests'] = formatted_tests + if solved_test.test.name_and_passing_score()["name"] in dict_with_lists_of_test_results.keys(): + dict_with_lists_of_test_results[solved_test.test.name_and_passing_score()["name"]].insert(0, { + "name": solved_test.test.name_and_passing_score()["name"], + "passing_score": solved_test.test.name_and_passing_score()["passing_score"], + "score": solved_test.score, + "max": solved_test.max, + "percentage": solved_test.percentage, + "id": solved_test.test.id + }) + else: + dict_with_lists_of_test_results[solved_test.test.name_and_passing_score()["name"]] = [] + dict_with_lists_of_test_results[solved_test.test.name_and_passing_score()["name"]].append({ + "name": solved_test.test.name_and_passing_score()["name"], + "passing_score": solved_test.test.name_and_passing_score()["passing_score"], + "score": solved_test.score, + "max": solved_test.max, + "percentage": solved_test.percentage, + "id": solved_test.test.id + }) + context['tests_lists'] = dict_with_lists_of_test_results return render(request, 'solvedTests.html', context) -def editTest(request): - if request.POST: - # TODO here - # firstName = request.POST.get("firstName") - # lastName = request.POST.get("lastName") - # - # u = request.user - # u.first_name = firstName - # u.last_name = lastName - # u.save() - return redirect('myTests') - return render(request, 'editTest.html') +def solvedTestsDetailed(request, test_id): + context = {} + solved_tests = SolvedTest.objects.filter(test__id=test_id) + formatted_tests = list() + for solved_test in solved_tests: + formatted_tests.append({ + "passing_score": solved_test.test.name_and_passing_score()["passing_score"], + "score": solved_test.score, + "max": solved_test.max, + "percentage": solved_test.percentage, + "id": solved_test.test.id + }) + context['name'] = solved_tests[0].test.name_and_passing_score()["name"] + context['tests'] = formatted_tests + return render(request, 'solvedTestsDetailed.html', context) class EditTestTemplateView(TemplateView): -- 2.20.1 From 2721421c1dbaf45feb315000d4503784f8ea8fea Mon Sep 17 00:00:00 2001 From: Piotr Kopycki Date: Sat, 16 Apr 2022 17:05:39 +0200 Subject: [PATCH 03/12] New metadata, statistics and icons for tests --- config/settings.py | 1 + palette.txt | 4 +- requirements.txt | 1 + static/style.css | 59 ++++++++-- templates/base.html | 4 + templates/category.html | 99 ++++++++++++++++- templates/home.html | 101 +++++++++++++++++- templates/myTests.html | 99 ++++++++++++++++- templates/result.html | 20 +++- trials/migrations/0016_test_completions.py | 18 ++++ trials/migrations/0017_auto_20220416_1431.py | 33 ++++++ trials/migrations/0018_test_rates_amount.py | 18 ++++ ...9_rename_rates_amount_test_rates_amount.py | 18 ++++ trials/migrations/0020_auto_20220416_1634.py | 23 ++++ .../0021_remove_test_difficulty_label.py | 17 +++ trials/models.py | 21 +++- trials/urls.py | 3 +- trials/views.py | 32 +++++- 18 files changed, 542 insertions(+), 29 deletions(-) create mode 100644 trials/migrations/0016_test_completions.py create mode 100644 trials/migrations/0017_auto_20220416_1431.py create mode 100644 trials/migrations/0018_test_rates_amount.py create mode 100644 trials/migrations/0019_rename_rates_amount_test_rates_amount.py create mode 100644 trials/migrations/0020_auto_20220416_1634.py create mode 100644 trials/migrations/0021_remove_test_difficulty_label.py diff --git a/config/settings.py b/config/settings.py index fb0204c..f1ba50f 100644 --- a/config/settings.py +++ b/config/settings.py @@ -55,6 +55,7 @@ INSTALLED_APPS = [ "rest_framework_simplejwt", "django_extensions", "django_social_share", + 'fontawesomefree', "users", "trials", diff --git a/palette.txt b/palette.txt index 634cc57..91540aa 100644 --- a/palette.txt +++ b/palette.txt @@ -8,4 +8,6 @@ Buttons and links #00916E - Illuminating Emerald Main color: -#FF0B7E - Winter Sky \ No newline at end of file +#FF0B7E - Winter Sky + +#19647E - Blue Sapphire \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 63369f6..e8d6fc4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -109,3 +109,4 @@ wcwidth==0.2.5 webencodings==0.5.1 widgetsnbextension==3.5.2 zipp==3.6.0 +fontawesomefree==6.1.1 \ No newline at end of file diff --git a/static/style.css b/static/style.css index 338666a..ce253be 100644 --- a/static/style.css +++ b/static/style.css @@ -83,8 +83,8 @@ border-radius: 25px; border: 2px solid #FF0B7E; padding: 20px; - width: 800px; - height: 150px; + width: 750px; + height: 200px; } .mainTestName { @@ -115,12 +115,38 @@ } .mainTestMeta { - font-size: 13px; - padding-bottom: 40px; - color: #808080; + padding-bottom: 30px; /*transform: translate(150%,0%);*/ width:100%; - text-align:center; +} + +.mainTestMetaLine { + padding-bottom: 10px; + display: flex; + justify-content: space-between; +} + +.mainTestMetaInfoText { + width: 250px; + color: #808080; + font-size: 13px; + text-align: center; +} + +.mainTestMetaLineLabels { + padding-bottom: 10px; + padding-top: 10px; + margin-left: 15%; + margin-right: 15%; + display: flex; + justify-content: space-between; +} + +.mainTestMetaLabels { + font-weight: bold; + font-size: 16px; + color: #000000; + text-align: center; } .left { @@ -340,6 +366,15 @@ background-color:#FF0B7E padding-bottom: 15px; } +.resultContainer label { + font-weight: bold; + font-size: 20px; +} + +.resultContainerSpace { + padding-bottom: 15px; +} + .resultImage{ } @@ -498,4 +533,16 @@ background-color:#FF0B7E span { margin-right: 10px; +} + +.starChecked { + color: gold; +} + +.fireChecked { + color: red; +} + +.locked { + color: #19647E; } \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index d67e318..a462f5f 100644 --- a/templates/base.html +++ b/templates/base.html @@ -6,6 +6,10 @@ SOITA | {% block title %}{% endblock %} + + + + {% block additional_head %} {% endblock %} diff --git a/templates/category.html b/templates/category.html index d47d7ca..4deab7d 100644 --- a/templates/category.html +++ b/templates/category.html @@ -14,11 +14,104 @@
{{test.name}} + {% if test.password != "" %} + + {% endif %}
-
Kategoria: {{test.category}}
-
Próg zaliczenia: {{test.passing_score}}
-
Liczba pytań: {{test.question_count}}
+
+
Kategoria: {{test.category}}
+
Autor: {{test.get_author_name}}
+
Rozwiązania: {{test.completions}}
+
+
+
Próg zaliczenia: {{test.passing_score}}
+
Maksymalna ilość punktów: {{test.get_maxscore}}
+
Ilość pytań: {{test.question_count}}
+
+
+
+ Trudność: + {% if test.avg_difficulty == 0.0 %} + + + + + + {% elif test.avg_difficulty < 20.0 %} + + > + > + > + > + {% elif test.avg_difficulty < 40.0 %} + + + + + + {% elif test.avg_difficulty < 60.0 %} + + + + + + {% elif test.avg_difficulty < 80.0 %} + + + + + + {% else %} + + + + + + {% endif %} +
+
+ Ocena: + {% if test.avg_rating == 0 %} + + + + + + {% elif test.avg_rating == 1 %} + + + + + + {% elif test.avg_rating == 2 %} + + + + + + {% elif test.avg_rating == 3 %} + + + + + + {% elif test.avg_rating == 4 %} + + + + + + {% else %} + + + + + + {% endif %} + (Głosy: {{test.rates_amount}}) +
+
diff --git a/templates/home.html b/templates/home.html index 7b00cfc..e6d7280 100644 --- a/templates/home.html +++ b/templates/home.html @@ -8,17 +8,108 @@
{{test.name}} - + {% if test.password != "" %} + + {% endif %}
-
Kategoria: {{test.category}}
-
Próg zaliczenia: {{test.passing_score}}
-
Liczba pytań: {{test.question_count}}
+
+
Kategoria: {{test.category}}
+
Autor: {{test.get_author_name}}
+
Rozwiązania: {{test.completions}}
+
+
+
Próg zaliczenia: {{test.passing_score}}
+
Maksymalna ilość punktów: {{test.get_maxscore}}
+
Ilość pytań: {{test.question_count}}
+
+
+
+ Trudność: + {% if test.avg_difficulty == 0.0 %} + + + + + + {% elif test.avg_difficulty < 20.0 %} + + > + > + > + > + {% elif test.avg_difficulty < 40.0 %} + + + + + + {% elif test.avg_difficulty < 60.0 %} + + + + + + {% elif test.avg_difficulty < 80.0 %} + + + + + + {% else %} + + + + + + {% endif %} +
+
+ Ocena: + {% if test.avg_rating == 0 %} + + + + + + {% elif test.avg_rating == 1 %} + + + + + + {% elif test.avg_rating == 2 %} + + + + + + {% elif test.avg_rating == 3 %} + + + + + + {% elif test.avg_rating == 4 %} + + + + + + {% else %} + + + + + + {% endif %} + (Głosy: {{test.rates_amount}}) +
+
-{# #}

diff --git a/templates/myTests.html b/templates/myTests.html index cd9edd2..e91a92c 100644 --- a/templates/myTests.html +++ b/templates/myTests.html @@ -8,11 +8,104 @@
{{test.name}} + {% if test.password != "" %} + + {% endif %}
-
Kategoria: {{test.category}}
-
Próg zaliczenia: {{test.passing_score}}
-
Liczba pytań: {{test.question_count}}
+
+
Kategoria: {{test.category}}
+
Autor: {{test.get_author_name}}
+
Rozwiązania: {{test.completions}}
+
+
+
Próg zaliczenia: {{test.passing_score}}
+
Maksymalna ilość punktów: {{test.get_maxscore}}
+
Ilość pytań: {{test.question_count}}
+
+
+
+ Trudność: + {% if test.avg_difficulty == 0.0 %} + + + + + + {% elif test.avg_difficulty < 20.0 %} + + > + > + > + > + {% elif test.avg_difficulty < 40.0 %} + + + + + + {% elif test.avg_difficulty < 60.0 %} + + + + + + {% elif test.avg_difficulty < 80.0 %} + + + + + + {% else %} + + + + + + {% endif %} +
+
+ Ocena: + {% if test.avg_rating == 0 %} + + + + + + {% elif test.avg_rating == 1 %} + + + + + + {% elif test.avg_rating == 2 %} + + + + + + {% elif test.avg_rating == 3 %} + + + + + + {% elif test.avg_rating == 4 %} + + + + + + {% else %} + + + + + + {% endif %} + (Głosy: {{test.rates_amount}}) +
+
diff --git a/templates/result.html b/templates/result.html index cc9d086..80b072c 100644 --- a/templates/result.html +++ b/templates/result.html @@ -26,13 +26,29 @@
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 %} + +

+
diff --git a/trials/migrations/0016_test_completions.py b/trials/migrations/0016_test_completions.py new file mode 100644 index 0000000..487812d --- /dev/null +++ b/trials/migrations/0016_test_completions.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2022-04-16 12:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('trials', '0015_test_password'), + ] + + operations = [ + migrations.AddField( + model_name='test', + name='completions', + field=models.IntegerField(default=0), + ), + ] diff --git a/trials/migrations/0017_auto_20220416_1431.py b/trials/migrations/0017_auto_20220416_1431.py new file mode 100644 index 0000000..87f761b --- /dev/null +++ b/trials/migrations/0017_auto_20220416_1431.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.9 on 2022-04-16 12:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('trials', '0016_test_completions'), + ] + + operations = [ + migrations.AddField( + model_name='test', + name='difficulty_label', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='test', + name='rating_label', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='test', + name='total_percentage_scored_by_users', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='test', + name='total_rating', + field=models.IntegerField(default=0), + ), + ] diff --git a/trials/migrations/0018_test_rates_amount.py b/trials/migrations/0018_test_rates_amount.py new file mode 100644 index 0000000..2f724fc --- /dev/null +++ b/trials/migrations/0018_test_rates_amount.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2022-04-16 13:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('trials', '0017_auto_20220416_1431'), + ] + + operations = [ + migrations.AddField( + model_name='test', + name='rates_Amount', + field=models.IntegerField(default=0), + ), + ] diff --git a/trials/migrations/0019_rename_rates_amount_test_rates_amount.py b/trials/migrations/0019_rename_rates_amount_test_rates_amount.py new file mode 100644 index 0000000..ba489ee --- /dev/null +++ b/trials/migrations/0019_rename_rates_amount_test_rates_amount.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2022-04-16 13:23 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('trials', '0018_test_rates_amount'), + ] + + operations = [ + migrations.RenameField( + model_name='test', + old_name='rates_Amount', + new_name='rates_amount', + ), + ] diff --git a/trials/migrations/0020_auto_20220416_1634.py b/trials/migrations/0020_auto_20220416_1634.py new file mode 100644 index 0000000..23fc95e --- /dev/null +++ b/trials/migrations/0020_auto_20220416_1634.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.9 on 2022-04-16 14:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('trials', '0019_rename_rates_amount_test_rates_amount'), + ] + + operations = [ + migrations.RenameField( + model_name='test', + old_name='rating_label', + new_name='avg_rating', + ), + migrations.AddField( + model_name='test', + name='avg_difficulty', + field=models.FloatField(default=0.0), + ), + ] diff --git a/trials/migrations/0021_remove_test_difficulty_label.py b/trials/migrations/0021_remove_test_difficulty_label.py new file mode 100644 index 0000000..6570bc5 --- /dev/null +++ b/trials/migrations/0021_remove_test_difficulty_label.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.9 on 2022-04-16 14:36 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('trials', '0020_auto_20220416_1634'), + ] + + operations = [ + migrations.RemoveField( + model_name='test', + name='difficulty_label', + ), + ] diff --git a/trials/models.py b/trials/models.py index e91e07d..d6c499f 100644 --- a/trials/models.py +++ b/trials/models.py @@ -1,6 +1,7 @@ from django.db import models from questions.models import Question +from users.models import User from .managers import TestManager @@ -22,7 +23,12 @@ class Test(models.Model): on_delete=models.CASCADE ) password = models.CharField(max_length=100, default="") - + 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) + avg_difficulty = models.FloatField(default=0.0) objects = TestManager() def get_score(self, answers): @@ -45,7 +51,7 @@ class Test(models.Model): points += question.points return points - def get_maxscore(self, answers): + def get_maxscore(self): """ [ { @@ -59,9 +65,6 @@ class Test(models.Model): ] """ points = 0 - # for answer in answers: - # question = self.questions.get(id=answer["question"]) - # points += question.points for question in self.questions.all(): points += question.points return points @@ -69,6 +72,14 @@ class Test(models.Model): def question_count(self): return Question.objects.filter(test_id=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, diff --git a/trials/urls.py b/trials/urls.py index fab316a..c689e6f 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, addTest, addQuestions, myTests, solvedTests, solvedTestsDetailed, EditTestTemplateView, deleteTest, AddQuestionToExistingTest, RemoveQuestionFromExistingTest, EditQuestionTemplateView, editName, editVisible, editPassword, TestPasswordTemplateView +from trials.views import TestModelViewSet, TestTemplateView, TestValidateAPIView, TestResultView, rateTest, addTest, addQuestions, myTests, solvedTests, solvedTestsDetailed, EditTestTemplateView, deleteTest, AddQuestionToExistingTest, RemoveQuestionFromExistingTest, EditQuestionTemplateView, editName, editVisible, editPassword, TestPasswordTemplateView router = DefaultRouter(trailing_slash=False) router.register("items", TestModelViewSet) @@ -11,6 +11,7 @@ urlpatterns = [ path('/password', TestPasswordTemplateView), path('/mark', TestValidateAPIView.as_view()), path('/result', TestResultView.as_view()), + path('/rateTest', rateTest, name="rateTest"), path('/edit', EditTestTemplateView.as_view()), path('/add-question', AddQuestionToExistingTest.as_view()), path('/remove-question', RemoveQuestionFromExistingTest.as_view()), diff --git a/trials/views.py b/trials/views.py index 4781553..1908b23 100644 --- a/trials/views.py +++ b/trials/views.py @@ -301,6 +301,17 @@ def editPassword(request, test_id): return redirect(f'/tests/{test_id}/edit') +def rateTest(request, test_id): + test = Test.objects.get(id=test_id) + rate = request.GET["rate"] + test.rates_amount += 1 + test.total_rating += int(rate) + avg_rating = test.total_rating / test.rates_amount + test.avg_rating = int(avg_rating) + test.save() + return redirect(f'/tests/{test_id}/result') + + class TestModelViewSet(viewsets.ModelViewSet): queryset = Test.objects.all() serializer_class = TestSerializer @@ -332,8 +343,8 @@ class TestTemplateView(TemplateView): def get_score(self, test: Test, answers): return test.get_score(answers) - def get_maxscore(self, test: Test, answers): - return test.get_maxscore(answers) + def get_maxscore(self, test: Test): + return test.get_maxscore() def formatted_responses(self, unformatted_json): formatted_response = list() @@ -349,7 +360,7 @@ class TestTemplateView(TemplateView): def post(self, request, *args, **kwargs): test = Test.objects.get(id=kwargs.get("test_id")) score = self.get_score(test, self.formatted_responses(request.POST)) - max = self.get_maxscore(test, self.formatted_responses(request.POST)) + max = self.get_maxscore(test) status = score >= test.passing_score # context = { # "status": self.PASSED.get(status, self.UNKNOWN), @@ -372,6 +383,21 @@ class TestTemplateView(TemplateView): user=request.user, test=test ) + test.completions += 1 + test.total_percentage_scored_by_users += int(score / max * 100) + if test.completions >= 5: + test.avg_difficulty = float(test.total_percentage_scored_by_users) / float(test.completions) + if test.avg_difficulty > 90.0: + test.difficulty_label = 1 + elif test.avg_difficulty > 75.0: + test.difficulty_label = 2 + elif test.avg_difficulty > 50.0: + test.difficulty_label = 3 + elif test.avg_difficulty > 25.0: + test.difficulty_label = 4 + else: + test.difficulty_label = 5 + test.save() return HttpResponseRedirect(f'result') -- 2.20.1 From f6445a18e43c7bf9abaec5aa315c486eb2989c63 Mon Sep 17 00:00:00 2001 From: Piotr Kopycki Date: Sat, 16 Apr 2022 17:08:08 +0200 Subject: [PATCH 04/12] Hotfix - icon tooltip translation --- templates/category.html | 2 +- templates/home.html | 2 +- templates/myTests.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/category.html b/templates/category.html index 4deab7d..132326a 100644 --- a/templates/category.html +++ b/templates/category.html @@ -15,7 +15,7 @@
{{test.name}} {% if test.password != "" %} - + {% endif %}
diff --git a/templates/home.html b/templates/home.html index e6d7280..f119747 100644 --- a/templates/home.html +++ b/templates/home.html @@ -9,7 +9,7 @@
{{test.name}} {% if test.password != "" %} - + {% endif %}
diff --git a/templates/myTests.html b/templates/myTests.html index e91a92c..29abbb3 100644 --- a/templates/myTests.html +++ b/templates/myTests.html @@ -9,7 +9,7 @@
{{test.name}} {% if test.password != "" %} - + {% endif %}
-- 2.20.1 From c19d81a92ce65b09a4ce67f8401c9a208b6fcb24 Mon Sep 17 00:00:00 2001 From: Piotr Kopycki Date: Sun, 15 May 2022 16:01:52 +0200 Subject: [PATCH 05/12] Page with popular and hard test. Icons in side menu --- config/settings.py | 1 + config/urls.py | 4 +- config/views.py | 15 +++++ static/script.js | 21 +++++++ static/style.css | 21 ++++++- templates/base.html | 24 ++++--- templates/category.html | 10 +-- templates/createTestNew.html | 10 +++ templates/hard.html | 118 +++++++++++++++++++++++++++++++++++ templates/home.html | 12 ++-- templates/popular.html | 118 +++++++++++++++++++++++++++++++++++ trials/models.py | 1 + trials/serializers.py | 8 +++ trials/urls.py | 2 +- trials/views.py | 21 ++++--- 15 files changed, 353 insertions(+), 33 deletions(-) create mode 100644 static/script.js create mode 100644 templates/createTestNew.html create mode 100644 templates/hard.html create mode 100644 templates/popular.html diff --git a/config/settings.py b/config/settings.py index f1ba50f..c7d6522 100644 --- a/config/settings.py +++ b/config/settings.py @@ -56,6 +56,7 @@ INSTALLED_APPS = [ "django_extensions", "django_social_share", 'fontawesomefree', + "jquery", "users", "trials", diff --git a/config/urls.py b/config/urls.py index e2c4f31..b882af1 100644 --- a/config/urls.py +++ b/config/urls.py @@ -16,12 +16,14 @@ Including another URLconf from django.contrib import admin from django.urls import include from django.urls import path -from .views import home, welcome, help +from .views import home, welcome, help, hard, popular from django.contrib.staticfiles.urls import staticfiles_urlpatterns urlpatterns = [ path('', welcome, name='welcome'), path('home', home, name='home'), + path('popular', popular, name='popular'), + path('hard', hard, name='hard'), path('help', help, name='help'), path('users/', include("users.urls")), path('questions/', include("questions.urls")), diff --git a/config/views.py b/config/views.py index a6157b1..cd37137 100644 --- a/config/views.py +++ b/config/views.py @@ -2,6 +2,7 @@ from django.shortcuts import render, redirect from django.template import loader from django.contrib.auth.decorators import login_required from trials.models import Test +import operator @login_required @@ -18,6 +19,20 @@ def home(request): def help(request): return render(request, 'help.html', ) +@login_required +def popular(request): + context = {} + context['tests'] = Test.objects.filter(avg_rating__gt=0) + context['tests'] = sorted(context['tests'], key=operator.attrgetter('avg_rating'), reverse=True) + return render(request, 'popular.html', context) + +@login_required +def hard(request): + context = {} + context['tests'] = Test.objects.filter(difficulty_label__gt=0) + context['tests'] = sorted(context['tests'], key=operator.attrgetter('difficulty_label'), reverse=True) + return render(request, 'hard.html', context) + def welcome(request): return render(request, 'welcome.html') diff --git a/static/script.js b/static/script.js new file mode 100644 index 0000000..0b8e7bd --- /dev/null +++ b/static/script.js @@ -0,0 +1,21 @@ +//$(function() { +// $(".newQuestionSection" ).draggable().resizable(); +//} ); + +var questionId = 1; + +$('.addQuestionButton').click(function(){ + console.log("REEEEEEEE") + // Clone extra box, and remove duplicate ids + let clone = $("#question-copy").clone().removeAttr("hidden"); + clone.id = "question"- + ++questionId; + //clone.find("*").removeAttr("id"); + clone.find("*").each(function() { + $(this).attr("id", "q" + questionId + "-" + $(this).attr("id")); + }); + clone.find("input:radio").each(function() { + $(this).attr("name", questionId); + }); + // append it to div + $('#canvas').append(clone); +}); \ No newline at end of file diff --git a/static/style.css b/static/style.css index ce253be..080d606 100644 --- a/static/style.css +++ b/static/style.css @@ -1,6 +1,6 @@ .sidenav { height: 100%; - width: 195px; + width: 215px; position: fixed; z-index: 1; top: 0; @@ -44,7 +44,7 @@ } .main { - margin-left: 190px; + margin-left: 215px; padding: 0px 40px; } @@ -515,6 +515,23 @@ background-color:#FF0B7E width: 500px; } +.newQuestionSection { + border-radius: 25px; + border: 2px solid #FF0B7E; + padding: 20px; + width: 750px; + height: 350px; +} + +.questionSectionLabelText { + font-weight: bold; + font-size: 16px; + padding-bottom: 20px; +} + +.addQuestionButton { +} + .editContainer { overflow: scroll; } diff --git a/templates/base.html b/templates/base.html index a462f5f..2a0a349 100644 --- a/templates/base.html +++ b/templates/base.html @@ -16,11 +16,14 @@
- {% block content %} - {% endblock %} +
+ {% block content %} + {% endblock %} +
diff --git a/templates/category.html b/templates/category.html index 132326a..c3b75d7 100644 --- a/templates/category.html +++ b/templates/category.html @@ -32,31 +32,31 @@
Trudność: - {% if test.avg_difficulty == 0.0 %} + {% if test.difficulty_label == 0 %} - {% elif test.avg_difficulty < 20.0 %} + {% elif test.difficulty_label == 1 %} > > > > - {% elif test.avg_difficulty < 40.0 %} + {% elif test.difficulty_label == 2 %} - {% elif test.avg_difficulty < 60.0 %} + {% elif test.difficulty_label == 3 %} - {% elif test.avg_difficulty < 80.0 %} + {% elif test.difficulty_label == 4 %} diff --git a/templates/createTestNew.html b/templates/createTestNew.html new file mode 100644 index 0000000..4bdcfcb --- /dev/null +++ b/templates/createTestNew.html @@ -0,0 +1,10 @@ + + + + + $Title$ + + +$END$ + + \ No newline at end of file diff --git a/templates/hard.html b/templates/hard.html new file mode 100644 index 0000000..d95a485 --- /dev/null +++ b/templates/hard.html @@ -0,0 +1,118 @@ +{% extends "base.html" %} + +{% block title %}Główna{% endblock %} + +{% block content %} +

Najtrudniejsze testy:

+ {% for test in tests %} +
+
+ {{test.name}} + {% if test.password != "" %} + + {% endif %} +
+
+
+
Kategoria: {{test.category}}
+
Autor: {{test.get_author_name}}
+
Rozwiązania: {{test.completions}}
+
+
+
Próg zaliczenia: {{test.passing_score}}
+
Maksymalna ilość punktów: {{test.get_maxscore}}
+
Ilość pytań: {{test.question_count}}
+
+
+
+ Trudność: + {% if test.difficulty_label == 0 %} + + + + + + {% elif test.difficulty_label == 1 %} + + > + > + > + > + {% elif test.difficulty_label == 2 %} + + + + + + {% elif test.difficulty_label == 3 %} + + + + + + {% elif test.difficulty_label == 4 %} + + + + + + {% else %} + + + + + + {% endif %} +
+
+ Ocena: + {% if test.avg_rating == 0 %} + + + + + + {% elif test.avg_rating == 1 %} + + + + + + {% elif test.avg_rating == 2 %} + + + + + + {% elif test.avg_rating == 3 %} + + + + + + {% elif test.avg_rating == 4 %} + + + + + + {% else %} + + + + + + {% endif %} + (Głosy: {{test.rates_amount}}) +
+
+
+ + + + +
+
+ {% endfor %} +{% endblock %} + diff --git a/templates/home.html b/templates/home.html index f119747..d57bd6b 100644 --- a/templates/home.html +++ b/templates/home.html @@ -3,7 +3,7 @@ {% block title %}Główna{% endblock %} {% block content %} -

Rozwiąż jakiś test!

+

Najnowsze testy:

{% for test in tests %}
@@ -26,31 +26,31 @@
Trudność: - {% if test.avg_difficulty == 0.0 %} + {% if test.difficulty_label == 0 %} - {% elif test.avg_difficulty < 20.0 %} + {% elif test.difficulty_label == 1 %} > > > > - {% elif test.avg_difficulty < 40.0 %} + {% elif test.difficulty_label == 2 %} - {% elif test.avg_difficulty < 60.0 %} + {% elif test.difficulty_label == 3 %} - {% elif test.avg_difficulty < 80.0 %} + {% elif test.difficulty_label == 4 %} diff --git a/templates/popular.html b/templates/popular.html new file mode 100644 index 0000000..7c6ce28 --- /dev/null +++ b/templates/popular.html @@ -0,0 +1,118 @@ +{% extends "base.html" %} + +{% block title %}Główna{% endblock %} + +{% block content %} +

Najpopularniejsze testy:

+ {% for test in tests %} +
+
+ {{test.name}} + {% if test.password != "" %} + + {% endif %} +
+
+
+
Kategoria: {{test.category}}
+
Autor: {{test.get_author_name}}
+
Rozwiązania: {{test.completions}}
+
+
+
Próg zaliczenia: {{test.passing_score}}
+
Maksymalna ilość punktów: {{test.get_maxscore}}
+
Ilość pytań: {{test.question_count}}
+
+
+
+ Trudność: + {% if test.difficulty_label == 0 %} + + + + + + {% elif test.difficulty_label == 1 %} + + > + > + > + > + {% elif test.difficulty_label == 2 %} + + + + + + {% elif test.difficulty_label == 3 %} + + + + + + {% elif test.difficulty_label == 4 %} + + + + + + {% else %} + + + + + + {% endif %} +
+
+ Ocena: + {% if test.avg_rating == 0 %} + + + + + + {% elif test.avg_rating == 1 %} + + + + + + {% elif test.avg_rating == 2 %} + + + + + + {% elif test.avg_rating == 3 %} + + + + + + {% elif test.avg_rating == 4 %} + + + + + + {% else %} + + + + + + {% endif %} + (Głosy: {{test.rates_amount}}) +
+
+
+ + + + +
+
+ {% endfor %} +{% endblock %} + diff --git a/trials/models.py b/trials/models.py index d6c499f..56c8f4d 100644 --- a/trials/models.py +++ b/trials/models.py @@ -28,6 +28,7 @@ class Test(models.Model): 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 = TestManager() diff --git a/trials/serializers.py b/trials/serializers.py index fa5683c..0f938ed 100644 --- a/trials/serializers.py +++ b/trials/serializers.py @@ -19,6 +19,14 @@ class TestSerializer(serializers.ModelSerializer): "questions", "visible", "category", + "created_by", + "completions", + "total_percentage_scored_by_users", + "total_rating", + "avg_rating", + "rates_amount", + "difficulty_label", + "avg_difficulty" ) def create(self, validated_data): diff --git a/trials/urls.py b/trials/urls.py index c689e6f..c563442 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 +from trials.views import TestModelViewSet, TestTemplateView, TestValidateAPIView, TestResultView, rateTest, addTest, addTest2, addQuestions, myTests, solvedTests, solvedTestsDetailed, EditTestTemplateView, deleteTest, AddQuestionToExistingTest, RemoveQuestionFromExistingTest, EditQuestionTemplateView, editName, editVisible, editPassword, TestPasswordTemplateView router = DefaultRouter(trailing_slash=False) router.register("items", TestModelViewSet) diff --git a/trials/views.py b/trials/views.py index 1908b23..90efd21 100644 --- a/trials/views.py +++ b/trials/views.py @@ -18,12 +18,12 @@ from django.template import loader from django.template.loader import render_to_string, get_template from django.http import HttpRequest import requests +from django.contrib.auth.decorators import login_required - +@login_required def addTest(request): return render(request, 'createTest.html') - def is_visible(visible): if visible =="public": return True @@ -144,14 +144,14 @@ class RemoveQuestionFromExistingTest(TemplateView): Question.objects.get(id=request.POST["id"]).delete() return redirect(f'/tests/{kwargs["test_id"]}/edit') - +@login_required def myTests(request): context = {} user = request.user.id context['tests'] = Test.objects.filter(created_by=user) return render(request, 'myTests.html', context) - +@login_required def solvedTests(request): context = {} user_id = request.user.id @@ -180,7 +180,7 @@ def solvedTests(request): context['tests_lists'] = dict_with_lists_of_test_results return render(request, 'solvedTests.html', context) - +@login_required def solvedTestsDetailed(request, test_id): context = {} solved_tests = SolvedTest.objects.filter(test__id=test_id) @@ -268,12 +268,12 @@ class EditQuestionTemplateView(TemplateView): Question.objects.EditQuestion(question_id=question_id, name=description, answers=answers) return redirect(f'/tests/{test}/edit') - +@login_required def deleteTest(request, test_id): Test.objects.filter(id=test_id).delete() return redirect('myTests') - +@login_required def editVisible(request, test_id): new_visible = request.GET["visible"] if new_visible == "public": @@ -285,6 +285,7 @@ def editVisible(request, test_id): test.save() return redirect(f'/tests/{test_id}/edit') +@login_required def editName(request, test_id): new_name = request.GET["name"] test = Test.objects.get(id=test_id) @@ -292,7 +293,7 @@ def editName(request, test_id): test.save() return redirect(f'/tests/{test_id}/edit') - +@login_required def editPassword(request, test_id): new_password = request.GET["password"] test = Test.objects.get(id=test_id) @@ -300,7 +301,7 @@ def editPassword(request, test_id): test.save() return redirect(f'/tests/{test_id}/edit') - +@login_required def rateTest(request, test_id): test = Test.objects.get(id=test_id) rate = request.GET["rate"] @@ -401,6 +402,7 @@ class TestTemplateView(TemplateView): return HttpResponseRedirect(f'result') +@login_required def TestPasswordTemplateView(request, test_id): test = Test.objects.get(id=test_id) if test.password == "": @@ -411,6 +413,7 @@ def TestPasswordTemplateView(request, test_id): return render(request, 'testPassword.html') +@login_required def testView(request): permission_classes = [] template_name = settings.BASE_DIR + f"/templates/generic_test.html" -- 2.20.1 From dd22e1ca8359f14e4c7abbf0fec8f4a3423b2c82 Mon Sep 17 00:00:00 2001 From: Piotr Kopycki Date: Sun, 15 May 2022 17:27:36 +0200 Subject: [PATCH 06/12] hotfix --- templates/questionnaire.html | 10 ++++++++++ trials/urls.py | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 templates/questionnaire.html diff --git a/templates/questionnaire.html b/templates/questionnaire.html new file mode 100644 index 0000000..de155ea --- /dev/null +++ b/templates/questionnaire.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/trials/urls.py b/trials/urls.py index c563442..c689e6f 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, addTest2, addQuestions, myTests, solvedTests, solvedTestsDetailed, EditTestTemplateView, deleteTest, AddQuestionToExistingTest, RemoveQuestionFromExistingTest, EditQuestionTemplateView, editName, editVisible, editPassword, TestPasswordTemplateView +from trials.views import TestModelViewSet, TestTemplateView, TestValidateAPIView, TestResultView, rateTest, addTest, addQuestions, myTests, solvedTests, solvedTestsDetailed, EditTestTemplateView, deleteTest, AddQuestionToExistingTest, RemoveQuestionFromExistingTest, EditQuestionTemplateView, editName, editVisible, editPassword, TestPasswordTemplateView router = DefaultRouter(trailing_slash=False) router.register("items", TestModelViewSet) -- 2.20.1 From 55254762189fae393ffab27dbeb47b9540e91018 Mon Sep 17 00:00:00 2001 From: Piotr Kopycki Date: Sun, 15 May 2022 22:12:32 +0200 Subject: [PATCH 07/12] Questionnaire --- config/settings.py | 3 +- config/urls.py | 1 + config/views.py | 1 - questionnaire/__init__.py | 0 questionnaire/apps.py | 0 questionnaire/managers.py | 22 ++++++ questionnaire/migrations/__init__.py | 0 questionnaire/models.py | 22 ++++++ questionnaire/serializers.py | 28 ++++++++ questionnaire/urls.py | 12 ++++ questionnaire/views.py | 22 ++++++ templates/base.html | 1 + templates/hard.html | 2 +- templates/popular.html | 2 +- templates/questionnaire.html | 104 ++++++++++++++++++++++++--- 15 files changed, 207 insertions(+), 13 deletions(-) create mode 100644 questionnaire/__init__.py create mode 100644 questionnaire/apps.py create mode 100644 questionnaire/managers.py create mode 100644 questionnaire/migrations/__init__.py create mode 100644 questionnaire/models.py create mode 100644 questionnaire/serializers.py create mode 100644 questionnaire/urls.py create mode 100644 questionnaire/views.py diff --git a/config/settings.py b/config/settings.py index c7d6522..f357760 100644 --- a/config/settings.py +++ b/config/settings.py @@ -63,7 +63,8 @@ INSTALLED_APPS = [ "answers", "questions", "categories", - "tools" + "tools", + "questionnaire" ] # AUTHENTICATION_BACKENDS = ['config.authh.SettingsBackend'] MIDDLEWARE = [ diff --git a/config/urls.py b/config/urls.py index b882af1..fd0f475 100644 --- a/config/urls.py +++ b/config/urls.py @@ -30,6 +30,7 @@ urlpatterns = [ path('answers/', include("answers.urls")), path('tests/', include("trials.urls")), path('category/', include("categories.urls")), + path('questionnaire/', include("questionnaire.urls")), ] urlpatterns += staticfiles_urlpatterns() diff --git a/config/views.py b/config/views.py index cd37137..fc02746 100644 --- a/config/views.py +++ b/config/views.py @@ -33,6 +33,5 @@ def hard(request): context['tests'] = sorted(context['tests'], key=operator.attrgetter('difficulty_label'), reverse=True) return render(request, 'hard.html', context) - def welcome(request): return render(request, 'welcome.html') diff --git a/questionnaire/__init__.py b/questionnaire/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/questionnaire/apps.py b/questionnaire/apps.py new file mode 100644 index 0000000..e69de29 diff --git a/questionnaire/managers.py b/questionnaire/managers.py new file mode 100644 index 0000000..599759e --- /dev/null +++ b/questionnaire/managers.py @@ -0,0 +1,22 @@ +from django.db.models import Manager +from django.apps import apps +from django.conf import settings + +class QuestionnaireManager(Manager): + + def create( + self, + **kwargs + ): + instance = super().create( + overall=kwargs.get("overall"), + functionality=kwargs.get("functionality"), + look=kwargs.get("look"), + intuitive=kwargs.get("intuitive"), + bugs=kwargs.get("bugs"), + tech=kwargs.get("tech"), + potential=kwargs.get("potential"), + worst=kwargs.get("worst"), + desc=kwargs.get("desc"), + ) + return instance diff --git a/questionnaire/migrations/__init__.py b/questionnaire/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/questionnaire/models.py b/questionnaire/models.py new file mode 100644 index 0000000..ecb2d03 --- /dev/null +++ b/questionnaire/models.py @@ -0,0 +1,22 @@ +from django.db import models + +from .managers import QuestionnaireManager + + +class Questionnaire(models.Model): + overall = models.IntegerField(default=0) + functionality = models.IntegerField(default=0) + look = models.IntegerField(default=0) + intuitive = models.IntegerField(default=0) + bugs = models.IntegerField(default=0) + tech = models.IntegerField(default=0) + potential = models.IntegerField(default=0) + worst = models.IntegerField(default=0) + desc = models.CharField(max_length=255, default="") + fill_by = models.ForeignKey( + "users.User", + null=True, + related_name="questionnaire", + on_delete=models.CASCADE + ) + objects = QuestionnaireManager() \ No newline at end of file diff --git a/questionnaire/serializers.py b/questionnaire/serializers.py new file mode 100644 index 0000000..d49b520 --- /dev/null +++ b/questionnaire/serializers.py @@ -0,0 +1,28 @@ +from rest_framework import serializers + +from questionnaire.models import Questionnaire + +class QuestionnaireSerializer(serializers.ModelSerializer): + + class Meta: + model = Questionnaire + fields = ( + "id", + "overall", + "functionality", + "look", + "intuitive", + "bugs", + "tech", + "potential", + "worst", + "desc", + "fill_by" + ) + + def create(self, validated_data): + instance = Questionnaire.objects.create( + **validated_data + ) + return instance + diff --git a/questionnaire/urls.py b/questionnaire/urls.py new file mode 100644 index 0000000..f56770e --- /dev/null +++ b/questionnaire/urls.py @@ -0,0 +1,12 @@ +from django.urls import path +from rest_framework.routers import DefaultRouter + +from .views import questionnaire + +router = DefaultRouter(trailing_slash=False) + +urlpatterns = [ + path('questionnaire', questionnaire, name='questionnaire') +] + +urlpatterns += router.urls \ No newline at end of file diff --git a/questionnaire/views.py b/questionnaire/views.py new file mode 100644 index 0000000..bc2f254 --- /dev/null +++ b/questionnaire/views.py @@ -0,0 +1,22 @@ +from django.shortcuts import render, redirect +from django.template import loader +from django.contrib.auth.decorators import login_required +from questionnaire.models import Questionnaire + + +@login_required +def questionnaire(request): + if request.POST: + overall = request.GET.get("overall") + functionality = request.GET.get("functionality") + look = request.GET.get("look") + intuitive = request.GET.get("intuitive") + bugs = request.GET.get("bugs") + tech = request.GET.get("tech") + potential = request.GET.get("potential") + worst = request.GET.get("worst") + desc = request.GET.get("desc") + Questionnaire.objects.create(overall=overall, functionality=functionality, look=look, intuitive=intuitive, + bugs=bugs, tech=tech, potential=potential, worst=worst, desc=desc) + return redirect('home') + return render(request, 'questionnaire.html') diff --git a/templates/base.html b/templates/base.html index 2a0a349..3e61332 100644 --- a/templates/base.html +++ b/templates/base.html @@ -38,6 +38,7 @@ Inne

Konto

Ustawienia + Ankieta Pomoc Wyloguj
diff --git a/templates/hard.html b/templates/hard.html index d95a485..f20fdc0 100644 --- a/templates/hard.html +++ b/templates/hard.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{% block title %}Główna{% endblock %} +{% block title %}Najtrudniejsze{% endblock %} {% block content %}

Najtrudniejsze testy:

diff --git a/templates/popular.html b/templates/popular.html index 7c6ce28..c08771c 100644 --- a/templates/popular.html +++ b/templates/popular.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{% block title %}Główna{% endblock %} +{% block title %}Najpopularniejsze{% endblock %} {% block content %}

Najpopularniejsze testy:

diff --git a/templates/questionnaire.html b/templates/questionnaire.html index de155ea..d6ba905 100644 --- a/templates/questionnaire.html +++ b/templates/questionnaire.html @@ -1,10 +1,96 @@ - - - - - Title - - +{% extends "base.html" %} - - \ No newline at end of file +{% block title %}Ankieta{% endblock %} + +{% block content %} +
+

Ankieta oceniająca działanie aplikacji:

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+

+
+
+{% endblock %} -- 2.20.1 From cff6de1dc09519c9a5bf18f47b208da80c787ab3 Mon Sep 17 00:00:00 2001 From: Hubert Jankowski Date: Sun, 15 May 2022 23:30:16 +0200 Subject: [PATCH 08/12] add migration --- questionnaire/migrations/0001_initial.py | 33 +++++++++++++++++++ .../migrations/0022_test_difficulty_label.py | 18 ++++++++++ 2 files changed, 51 insertions(+) create mode 100644 questionnaire/migrations/0001_initial.py create mode 100644 trials/migrations/0022_test_difficulty_label.py diff --git a/questionnaire/migrations/0001_initial.py b/questionnaire/migrations/0001_initial.py new file mode 100644 index 0000000..4daae12 --- /dev/null +++ b/questionnaire/migrations/0001_initial.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.9 on 2022-05-15 21:29 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Questionnaire', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('overall', models.IntegerField(default=0)), + ('functionality', models.IntegerField(default=0)), + ('look', models.IntegerField(default=0)), + ('intuitive', models.IntegerField(default=0)), + ('bugs', models.IntegerField(default=0)), + ('tech', models.IntegerField(default=0)), + ('potential', models.IntegerField(default=0)), + ('worst', models.IntegerField(default=0)), + ('desc', models.CharField(default='', max_length=255)), + ('fill_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='questionnaire', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/trials/migrations/0022_test_difficulty_label.py b/trials/migrations/0022_test_difficulty_label.py new file mode 100644 index 0000000..becfab6 --- /dev/null +++ b/trials/migrations/0022_test_difficulty_label.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2022-05-15 21:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('trials', '0021_remove_test_difficulty_label'), + ] + + operations = [ + migrations.AddField( + model_name='test', + name='difficulty_label', + field=models.IntegerField(default=0), + ), + ] -- 2.20.1 From 5e9d26ff8ecf3789572812bfa229aac19a4363b9 Mon Sep 17 00:00:00 2001 From: Hubert Jankowski Date: Sun, 15 May 2022 23:48:11 +0200 Subject: [PATCH 09/12] added user type --- users/models.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/users/models.py b/users/models.py index 7a0311e..3343166 100644 --- a/users/models.py +++ b/users/models.py @@ -5,6 +5,15 @@ from .managers import UserManager class User(AbstractBaseUser): + + ADMIN = "admin" + STANDARD = "standard" + + USER_TYPES = ( + ("admin", ADMIN), + ("standard", STANDARD), + ) + first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) @@ -14,6 +23,7 @@ class User(AbstractBaseUser): confirmation_number = models.CharField(max_length=100) reset_code = models.IntegerField(null=True) avatar = models.ImageField(upload_to="avatars/", null=True) + type = models.CharField(choices=USER_TYPES, default=STANDARD, max_length=100) USERNAME_FIELD = "email" -- 2.20.1 From b8e4d98b0500249e00d8d0ff7bb91d4cafcf3e74 Mon Sep 17 00:00:00 2001 From: Hubert Jankowski Date: Sun, 15 May 2022 23:57:42 +0200 Subject: [PATCH 10/12] user type --- templates/base.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/templates/base.html b/templates/base.html index 3e61332..f5d30f3 100644 --- a/templates/base.html +++ b/templates/base.html @@ -19,6 +19,9 @@ Strona główna Popularne Trudne + {% if user.type == "admin" %} + Stwórz turniej + {% endif %} Turnieje
Stwórz test -- 2.20.1 From 9bcf67756cf1feeaa3978a60c8cb0daa806e67f5 Mon Sep 17 00:00:00 2001 From: Hubert Jankowski Date: Sun, 15 May 2022 23:57:55 +0200 Subject: [PATCH 11/12] user type --- users/migrations/0005_user_type.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 users/migrations/0005_user_type.py diff --git a/users/migrations/0005_user_type.py b/users/migrations/0005_user_type.py new file mode 100644 index 0000000..3600d67 --- /dev/null +++ b/users/migrations/0005_user_type.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2022-05-15 21:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0004_alter_user_is_active'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='type', + field=models.CharField(choices=[('admin', 'admin'), ('standard', 'standard')], default='standard', max_length=100), + ), + ] -- 2.20.1 From 71cd22bbbb62976212012e4672736bfe48888356 Mon Sep 17 00:00:00 2001 From: Hubert Jankowski Date: Tue, 24 May 2022 21:01:45 +0200 Subject: [PATCH 12/12] add tournaments --- questions/models.py | 5 +++++ templates/base.html | 4 ++-- templates/createTournament.html | 28 ++++++++++++++++++++++++++++ templates/tournaments.html | 23 +++++++++++++++++++++++ trials/models.py | 13 ++++++++++++- trials/urls.py | 6 ++++-- trials/views.py | 11 ++++++++++- users/views.py | 3 ++- 8 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 templates/createTournament.html create mode 100644 templates/tournaments.html diff --git a/questions/models.py b/questions/models.py index 7e7ac72..fded3f9 100644 --- a/questions/models.py +++ b/questions/models.py @@ -19,4 +19,9 @@ class Question(models.Model): for answer in self.answers.all() ] + tournament = models.ManyToManyField( + "trials.Tournament", + null=True + ) + objects = QuestionManager() \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index f5d30f3..cc6cf8f 100644 --- a/templates/base.html +++ b/templates/base.html @@ -20,9 +20,9 @@ Popularne Trudne {% if user.type == "admin" %} - Stwórz turniej + Stwórz turniej {% endif %} - Turnieje + Turnieje
Stwórz test Twoje testy diff --git a/templates/createTournament.html b/templates/createTournament.html new file mode 100644 index 0000000..8b531a7 --- /dev/null +++ b/templates/createTournament.html @@ -0,0 +1,28 @@ +{% extends "base.html" %} + +{% block title %}Stwórz turniej{% endblock %} + +{% block content %} +

Stwórz turniej

+
+ {% for question in questions %} +
+
+ + {{ question.description }} +
+
+ {% for answer in question.answers.all %} + + {% endfor %} +
+ {% endfor %} +
+
+
+ +
+ +{% endblock %} diff --git a/templates/tournaments.html b/templates/tournaments.html new file mode 100644 index 0000000..dd7f7d2 --- /dev/null +++ b/templates/tournaments.html @@ -0,0 +1,23 @@ +{% extends "base.html" %} + +{% block title %}Turnieje{% endblock %} + +{% block content %} +

Twoje testy

+ {% for test in tests %} +
+
+ {{tournament.name}} + + + +
+ + + + +
+
+ {% endfor %} +{% endblock %} + diff --git a/trials/models.py b/trials/models.py index 56c8f4d..9894eb1 100644 --- a/trials/models.py +++ b/trials/models.py @@ -103,4 +103,15 @@ class SolvedTest(models.Model): null=True, related_name="answers", on_delete=models.CASCADE - ) \ No newline at end of file + ) + + +class Tournament(models.Model): + name = models.CharField(max_length=100) + created_by = models.ForeignKey( + "users.User", + null=True, + related_name="tournaments", + on_delete=models.CASCADE + ) + password = models.CharField(max_length=100) diff --git a/trials/urls.py b/trials/urls.py index c689e6f..9a8453f 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 +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 router = DefaultRouter(trailing_slash=False) router.register("items", TestModelViewSet) @@ -24,7 +24,9 @@ urlpatterns = [ path('add/questions', addQuestions, name="addQuestions"), path('my', myTests, name="myTests"), path('solved', solvedTests, name="solvedTests"), - path('solved/', solvedTestsDetailed, name="solvedTests") + path('solved/', solvedTestsDetailed, name="solvedTests"), + path('tournamets', TournamentView, name="tournaments"), + path('add/tournament', CreateTournamentView, name="CreateTournament") ] urlpatterns += router.urls diff --git a/trials/views.py b/trials/views.py index 90efd21..263c9fa 100644 --- a/trials/views.py +++ b/trials/views.py @@ -8,7 +8,7 @@ from rest_framework.response import Response from rest_framework.views import APIView from questions.models import Question -from trials.models import Test, SolvedTest +from trials.models import Test, SolvedTest, Tournament from trials.serializers import TestSerializer from django.conf import settings from django.shortcuts import render, redirect @@ -83,6 +83,15 @@ def addQuestions(request, **kwargs): return redirect('home') return render(request, 'addQuestions.html') +def TournamentView(request): + context = {} + context['tournament'] = Tournament.objects.all() + return render(request, 'tournaments.html', context) + +def CreateTournamentView(request): + context = {} + context['questions'] = Question.objects.all() + return render(request, 'createTournament.html', context) class AddQuestionToExistingTest(TemplateView): template_name = settings.BASE_DIR + f"/templates/addQuestionToExistingTest.html" diff --git a/users/views.py b/users/views.py index e685bba..81a0f7a 100644 --- a/users/views.py +++ b/users/views.py @@ -90,7 +90,8 @@ def register(request): email=form.cleaned_data["email"], first_name=form.cleaned_data["first_name"], last_name=form.cleaned_data["last_name"], - password=form.cleaned_data["password1"] + password=form.cleaned_data["password1"], + type="standard" ) return redirect('register_success') else: -- 2.20.1