diff --git a/Main/models/solution.py b/Main/models/solution.py index 0847b9d..6b1af46 100644 --- a/Main/models/solution.py +++ b/Main/models/solution.py @@ -8,7 +8,7 @@ from django.db.models import JSONField from django.db import models from django.utils import timezone -from Main.models import Set +from Main.models import Set, SetTask from Main.models.solution_file import SolutionFile from Main.models.task import Task from Sprint.settings import CONSTS @@ -32,6 +32,10 @@ class Solution(models.Model): models.Index(fields=['set', '-time_sent']), ] + @cached_property + def settask(self): + return SetTask.objects.filter(set=self.set, task=self.task).first() + @property def percentage_done(self): if self.test is None: diff --git a/Main/models/userinfo.py b/Main/models/userinfo.py index 21506d3..c9b0634 100644 --- a/Main/models/userinfo.py +++ b/Main/models/userinfo.py @@ -29,6 +29,9 @@ class UserInfo(models.Model): verified = models.BooleanField(default=False) teacher = models.BooleanField(default=False) + def __str__(self): + return self.surname + ' ' + self.name + @property def tasks_solved(self): fltr = Task.objects.filter(solution__result=CONSTS["ok_status"], solution__user=self.user).distinct() diff --git a/Main/templatetags/filters.py b/Main/templatetags/filters.py index 19de855..5089bb1 100644 --- a/Main/templatetags/filters.py +++ b/Main/templatetags/filters.py @@ -22,4 +22,14 @@ def settask(set, task): @register.filter('startswith') def startswith(s, prefix): - return s.startswith(prefix) + return s is not None and s.startswith(prefix) + + +@register.filter('make_pair') +def make_pair(user, task): + return user, task + + +@register.filter('get_info') +def get_info(data, pair): + return data.get(pair) diff --git a/Main/views/SolutionsTableView.py b/Main/views/SolutionsTableView.py index 3f2d247..f6d1625 100644 --- a/Main/views/SolutionsTableView.py +++ b/Main/views/SolutionsTableView.py @@ -13,10 +13,18 @@ class SolutionsTableView(BaseView): set: Optional[Set] = None task: Optional[Task] = None setTask: Optional[SetTask] = None + look: int + + @property + def view_file(self): + if self.look == 0: + return "solutions_table.html" + return "solutions_table_1.html" def pre_handle(self): if 'page' not in self.request.GET: raise AccessError() + self.look = int(self.request.GET['look'] or 0) self.page = int(self.request.GET['page']) if self.setTask is not None: self.set = self.setTask.set @@ -37,6 +45,16 @@ class SolutionsTableView(BaseView): raise AccessError() else: queryset = queryset.filter(user=self.request.user, task=self.task, set=self.set) + if self.look == 1: + data = dict() + users = set() + for solution in queryset.order_by('id'): # type: Solution + if (solution.user_id, solution.settask) not in data or data[(solution.user_id, solution.settask)] != 'OK': + data[(solution.user_id, solution.settask.id)] = solution.result + users.add(solution.user) + self.context['data'] = data + self.context['users'] = sorted(users, key=lambda u: str(u.userinfo)) + return offset = self.page_size * (self.page - 1) limit = self.page_size self.context["solutions"] = queryset.order_by("-id")[offset:offset + limit] diff --git a/templates/solution.html b/templates/solution.html index 590c6ed..c3a0934 100644 --- a/templates/solution.html +++ b/templates/solution.html @@ -50,7 +50,7 @@ Результат - {% if solution.result == testing_status %} {% endif %}{{ solution.result }} + {% if solution.result == testing_status %} {% endif %}{{ solution.result }} diff --git a/templates/solutions.html b/templates/solutions.html index bd8e30e..131dbb4 100644 --- a/templates/solutions.html +++ b/templates/solutions.html @@ -1,12 +1,25 @@ {% extends 'base_main.html' %} {% block scripts %} + var look = 0; var page = 1; + function setLook(number) { + look = number; + var n = number.toString(); + var butid = 'button' + n; + document.getElementById(butid).classList.add('btn-dark'); + document.getElementById(butid).classList.remove('btn-light'); + document.getElementById(butid).focused = false; + butid = 'button' + (1 - number).toString(); + document.getElementById(butid).classList.remove('btn-dark'); + document.getElementById(butid).classList.add('btn-light'); + document.getElementById(butid).focused = false; + } function setPage(number) { page = number; } function doPoll() { - jQuery.get('/polling/solutions_table?{{ query }}&teacher=true&page=' + page.toString(), function(data) { + jQuery.get('/polling/solutions_table?{{ query }}&teacher=true&page=' + page.toString() + '&look=' + look.toString(), function(data) { var e = document.getElementById('solutions'); if (e.innerHTML !== data) e.innerHTML = data; @@ -24,7 +37,13 @@ {% block main %}

Решения {% if in_set %}{{ set.name }}{% else %}{{ task.name }}{% endif %}

-

Фильтр

+ + + + + +
+
{% endblock %} \ No newline at end of file diff --git a/templates/solutions_table.html b/templates/solutions_table.html index e884d42..49216b1 100644 --- a/templates/solutions_table.html +++ b/templates/solutions_table.html @@ -7,7 +7,7 @@ Язык Результат - + {% for solution in solutions %} diff --git a/templates/solutions_table_1.html b/templates/solutions_table_1.html new file mode 100644 index 0000000..f60cb8c --- /dev/null +++ b/templates/solutions_table_1.html @@ -0,0 +1,36 @@ +{% load filters %} + + + + + {% for task in set.settasks_ordered %} + + {% endfor %} + + + {% for user in users %} + + + {% for task in set.settasks_ordered %} + + {% endfor %} + + {% endfor %} + +
{{ task.name }}
{{ user.userinfo }} + {% with pair=user.id|make_pair:task.id %} + {% with result=data|get_info:pair %} + {% if result == in_queue_status %} + {{ result }} + {% else %}{% if result == ok_status %} + {{ result }} + {% else %}{% if result|startswith:testing_status %} + {{ result }} + {% else %}{% if result %} + {{ result }} + {% else %} + - + {% endif %}{% endif %}{% endif %}{% endif %} + {% endwith %} + {% endwith %} +
\ No newline at end of file