Browse Source

Merge branch 'data_migrations' into test

middleware_test
Pavel "LEdoian" Turinsky 4 years ago
parent
commit
738bb4fb2d
  1. 34
      data/sitetree.json
  2. 38
      seminar/templates/seminar/odevzdavatko/resitel_prehled.html
  3. 1
      seminar/templates/seminar/profil/resitel.html
  4. 12
      seminar/templatetags/deadliny.py
  5. 1
      seminar/urls.py
  6. 25
      seminar/views/odevzdavatko.py

34
data/sitetree.json

@ -695,13 +695,13 @@
"alias": null, "alias": null,
"description": "", "description": "",
"hidden": false, "hidden": false,
"hint": "", "hint": "To, co ŘEŠITELÉ poslali",
"inbreadcrumbs": true, "inbreadcrumbs": true,
"inmenu": true, "inmenu": true,
"insitetree": true, "insitetree": true,
"parent": 21, "parent": 21,
"sort_order": 37, "sort_order": 38,
"title": "Odevzdaná řešení", "title": "Došlá řešení",
"tree": 1, "tree": 1,
"url": "odevzdavatko_tabulka", "url": "odevzdavatko_tabulka",
"urlaspattern": true "urlaspattern": true
@ -724,7 +724,7 @@
"inmenu": true, "inmenu": true,
"insitetree": true, "insitetree": true,
"parent": 21, "parent": 21,
"sort_order": 38, "sort_order": 42,
"title": "Odhlásit se", "title": "Odhlásit se",
"tree": 1, "tree": 1,
"url": "logout", "url": "logout",
@ -806,5 +806,31 @@
}, },
"model": "sitetree.treeitem", "model": "sitetree.treeitem",
"pk": 41 "pk": 41
},
{
"fields": {
"access_guest": false,
"access_loggedin": false,
"access_perm_type": 1,
"access_permissions": [
2
],
"access_restricted": true,
"alias": null,
"description": "",
"hidden": false,
"hint": "To, co jsem JÁ odevzdal",
"inbreadcrumbs": true,
"inmenu": true,
"insitetree": true,
"parent": 21,
"sort_order": 37,
"title": "Odevzdaná řešení",
"tree": 1,
"url": "seminar_resitel_odevzdana_reseni",
"urlaspattern": true
},
"model": "sitetree.treeitem",
"pk": 42
} }
] ]

38
seminar/templates/seminar/odevzdavatko/resitel_prehled.html

@ -0,0 +1,38 @@
{% extends "base.html" %}
{% load static %}
{% load deadliny %}
{% block custom_css %}
<style type=text/css>
.dosla_reseni tr th {
text-align: center;
}
.dosla_reseni tr th, .dosla_reseni tr td {
border: 1px solid black;
padding: 1px 10px 1px 10px;
border-collapse: collapse;
}
</style>
{% endblock custom_css %}
{% block content %}
{% for rocnik, hodnoceni in podle_rocniku %}
<h1>Ročník {{ rocnik }}</h1>
<table class="dosla_reseni">
<tr>
<th>Doručeno</th>
<th>Problém</th>
<th>Body</th>
<th>Deadline</th>
</tr>
{% for hodn in hodnoceni %}
<tr>
<td>{{ hodn.reseni.cas_doruceni }}</td>
<td>{{ hodn.problem }}</td>
<td>{{ hodn.body|default_if_none:"---" }}</td>
<td>{{ hodn.reseni.cas_doruceni | deadline_html }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
{% endblock %}

1
seminar/templates/seminar/profil/resitel.html

@ -11,6 +11,7 @@
<a href="{% url 'logout' %}">Odhlásit se</a><br> <a href="{% url 'logout' %}">Odhlásit se</a><br>
<a href="{% url 'seminar_resitel_edit' %}">Upravit údaje</a><br> <a href="{% url 'seminar_resitel_edit' %}">Upravit údaje</a><br>
<a href="{% url 'seminar_resitel_odevzdana_reseni' %}">Odevzdaná řešení</a><br>
{% endblock %} {% endblock %}

12
seminar/templatetags/deadliny.py

@ -13,10 +13,20 @@ def deadline_text(datum):
} }
return strings[typ] return strings[typ]
@register.filter(name='deadline_kratseji')
def deadline_kratsi_text(datum):
typ, cislo, dl = deadline(datum)
strings = {
TypDeadline.PredDeadline: f"1. deadline {cislo}",
TypDeadline.SousDeadline: f"Soustřeďkový deadline {cislo}",
TypDeadline.FinalDeadline: f"Finální deadline {cislo}",
}
return strings[typ]
@register.filter(name='deadline_html') @register.filter(name='deadline_html')
def deadline_html(datum): def deadline_html(datum):
typ, _, _ = deadline(datum) typ, _, _ = deadline(datum)
text = deadline_text(datum) text = deadline_kratsi_text(datum)
classes = { classes = {
TypDeadline.PredDeadline: 'preddeadline', TypDeadline.PredDeadline: 'preddeadline',
TypDeadline.SousDeadline: 'sous_deadline', TypDeadline.SousDeadline: 'sous_deadline',

1
seminar/urls.py

@ -135,6 +135,7 @@ urlpatterns = [
path('prihlasit/', views.LoginView.as_view(), name='login'), path('prihlasit/', views.LoginView.as_view(), name='login'),
path('odhlasit/', views.LogoutView.as_view(), name='logout'), path('odhlasit/', views.LogoutView.as_view(), name='logout'),
path('resitel/', resitel_required(views.ResitelView.as_view()), name='seminar_resitel'), path('resitel/', resitel_required(views.ResitelView.as_view()), name='seminar_resitel'),
path('resitel/odevzdana_reseni/', resitel_required(views.PrehledOdevzdanychReseni.as_view()), name='seminar_resitel_odevzdana_reseni'),
path('reset-hesla/', views.PasswordResetView.as_view(), name='reset_password'), path('reset-hesla/', views.PasswordResetView.as_view(), name='reset_password'),
path('zmena-hesla/', views.PasswordChangeView.as_view(), name='change_password'), path('zmena-hesla/', views.PasswordChangeView.as_view(), name='change_password'),
path('reset-hesla/2/', views.PasswordResetDoneView.as_view(), name='reset_password_done'), path('reset-hesla/2/', views.PasswordResetDoneView.as_view(), name='reset_password_done'),

25
seminar/views/odevzdavatko.py

@ -25,6 +25,8 @@ logger = logging.getLogger(__name__)
# - ReseniProblemuView # - ReseniProblemuView
# - Detail konkrétního řešení -- všechny soubory, datum, ... # - Detail konkrétního řešení -- všechny soubory, datum, ...
# - DetailReseniView # - DetailReseniView
# - Pro řešitele: přehled jejich odevzdaných řešení
# - PrehledOdevzdanychReseni
# #
# Taky se může hodit: # Taky se může hodit:
# - Tabulka všech řešitelů x všech problémů? # - Tabulka všech řešitelů x všech problémů?
@ -238,6 +240,29 @@ def hodnoceniReseniView(request, pk, *args, **kwargs):
return redirect(success_url) return redirect(success_url)
class PrehledOdevzdanychReseni(ListView):
model = m.Hodnoceni
template_name = 'seminar/odevzdavatko/resitel_prehled.html'
def get_queryset(self):
if not self.request.user.is_authenticated:
raise RuntimeError("Uživatel měl být přihlášený!")
resitel = m.Resitel.objects.get(osoba__user=self.request.user)
qs = super().get_queryset()
qs = qs.filter(reseni__resitele__in=[resitel])
return qs
def get_context_data(self, *args, **kwargs):
ctx = super().get_context_data(*args, **kwargs)
# Ročník určujeme podle čísla, do jehož deadlinu došlo řešení.
# Chceme to mít seřazené, takže místo comphrerehsion ručně postavíme pole polí. Django templates neumí použít OrderedDict :-/
podle_rocniku = []
for rocnik, hodnoceni in groupby(ctx['object_list'], lambda ho: deadline(ho.reseni.cas_doruceni)[1].rocnik):
podle_rocniku.append((rocnik, list(hodnoceni)))
ctx['podle_rocniku'] = reversed(podle_rocniku) # Od nejnovějšího ročníku
# TODO: Umožnit stažení / zobrazení řešení
return ctx
# Přehled všech řešení kvůli debugování # Přehled všech řešení kvůli debugování
class SeznamReseniView(ListView): class SeznamReseniView(ListView):

Loading…
Cancel
Save