diff --git a/seminar/forms.py b/seminar/forms.py
index a7e0e404..0886f87d 100644
--- a/seminar/forms.py
+++ b/seminar/forms.py
@@ -301,3 +301,13 @@ class NahrajObrazekKTreeNoduForm(forms.ModelForm):
model = m.Obrazek
fields = ('na_web',)
+
+OhodnoceniReseniFormSet = inlineformset_factory(m.Reseni, m.Hodnoceni,
+ fields = ('problem', 'body', 'cislo_body'),
+ extra = 1,
+ widgets = {
+ 'problem': autocomplete.ModelSelect2(
+ url='autocomplete_problem_odevzdatelny', # FIXME: Dovolit i starší?
+ )
+ }
+ )
diff --git a/seminar/templates/seminar/odevzdavatko/detail.html b/seminar/templates/seminar/odevzdavatko/detail.html
index 6cee990d..24617dda 100644
--- a/seminar/templates/seminar/odevzdavatko/detail.html
+++ b/seminar/templates/seminar/odevzdavatko/detail.html
@@ -43,5 +43,9 @@
Ještě nebylo hodnoceno
{% endif %}
+
{% endblock %}
diff --git a/seminar/urls.py b/seminar/urls.py
index 7fa7b0a6..3d66526b 100644
--- a/seminar/urls.py
+++ b/seminar/urls.py
@@ -1,7 +1,7 @@
from django.urls import path, include, re_path
from django.contrib.auth.decorators import login_required
from . import views, export
-from .utils import org_required, resitel_required
+from .utils import org_required, resitel_required, viewMethodSwitch
from django.views.generic.base import RedirectView
urlpatterns = [
@@ -174,8 +174,7 @@ urlpatterns = [
path('temp/reseni/', org_required(views.TabulkaOdevzdanychReseniView.as_view()), name='odevzdavatko_tabulka'),
path('temp/reseni///', org_required(views.ReseniProblemuView.as_view()), name='odevzdavatko_reseni_resitele_k_problemu'),
- path('temp/reseni/', org_required(views.DetailReseniView.as_view()), name='odevzdavatko_detail_reseni'),
+ path('temp/reseni/', org_required(viewMethodSwitch(get=views.DetailReseniView.as_view(), post=views.HodnoceniReseniView.as_view())), name='odevzdavatko_detail_reseni'),
path('temp/reseni/all', org_required(views.SeznamReseniView.as_view())),
path('temp/reseni/akt', org_required(views.SeznamAktualnichReseniView.as_view())),
-
]
diff --git a/seminar/utils.py b/seminar/utils.py
index bcc67013..39abeae7 100644
--- a/seminar/utils.py
+++ b/seminar/utils.py
@@ -5,6 +5,7 @@ import datetime
from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import permission_required
from html.parser import HTMLParser
+from django import views as DjangoViews
from django.contrib.auth.models import AnonymousUser
from django.contrib.contenttypes.models import ContentType
@@ -191,3 +192,30 @@ def aktivniResitele(cislo, pouze_letosni=False):
else:
# spojíme querysety s řešiteli loni a letos do daného čísla
return (resi_v_rocniku(loni) | resi_v_rocniku(letos, cislo)).distinct()
+
+def viewMethodSwitch(get, post):
+ """
+ Vrátí view, který zavolá různé jiné views podle toho, kterou metodou je zavolán.
+
+ Inspirováno https://docs.djangoproject.com/en/3.1/topics/class-based-views/mixins/#an-alternative-better-solution, jen jsem to udělal genericky.
+
+ Parametry:
+ post view pro metodu POST
+ get view pro metodu GET
+
+ V obou případech se míní už view jakožto funkce, takže u class-based views se už má použít .as_view()
+
+ TODO: Podpora i pro metodu HEAD? A možná i pro FILES?
+ """
+
+ theGetView = get
+ thePostView = post
+
+ class NewView(DjangoViews.View):
+ def get(self, request, *args, **kwargs):
+ return theGetView(request, *args, **kwargs)
+ def post(self, request, *args, **kwargs):
+ return thePostView(request, *args, **kwargs)
+
+ return NewView.as_view()
+
diff --git a/seminar/views/odevzdavatko.py b/seminar/views/odevzdavatko.py
index de8ceec3..6a593740 100644
--- a/seminar/views/odevzdavatko.py
+++ b/seminar/views/odevzdavatko.py
@@ -1,10 +1,11 @@
-from django.views.generic import ListView, DetailView
-from django.views.generic.base import TemplateView
+from django.views.generic import ListView, DetailView, FormView
+from django.views.generic.detail import SingleObjectMixin
from dataclasses import dataclass
import datetime
import seminar.models as m
+import seminar.forms as f
from seminar.utils import aktivniResitele, resi_v_rocniku
# Co chceme?
@@ -109,10 +110,31 @@ class ReseniProblemuView(ListView):
# Kontext automaticky?
+## XXX: https://docs.djangoproject.com/en/3.1/topics/class-based-views/mixins/#avoid-anything-more-complex
class DetailReseniView(DetailView):
model = m.Reseni
template_name = 'seminar/odevzdavatko/detail.html'
- # To je všechno? Najde se to podle pk...
+
+ def aktualni_hodnoceni(self):
+ ...
+ return []
+
+ def get_context_data(self, **kw):
+ ctx = super().get_context_data(**kw)
+ ctx['form'] = f.OhodnoceniReseniFormSet(
+ initial = self.aktualni_hodnoceni()
+ )
+ return ctx
+
+
+class HodnoceniReseniView(SingleObjectMixin, FormView):
+ model = m.Reseni
+ template_name = 'seminar/odevzdavatko/detail.html'
+ form_class = f.OhodnoceniReseniFormSet
+
+ def form_vaild(self, form):
+ ...
+
# Přehled všech řešení kvůli debugování