Browse Source

WIP: odevzdávátkové formsety

export_seznamu_prednasek
Pavel "LEdoian" Turinsky 3 years ago
parent
commit
658f2a53c6
  1. 10
      seminar/forms.py
  2. 4
      seminar/templates/seminar/odevzdavatko/detail.html
  3. 5
      seminar/urls.py
  4. 28
      seminar/utils.py
  5. 28
      seminar/views/odevzdavatko.py

10
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ší?
)
}
)

4
seminar/templates/seminar/odevzdavatko/detail.html

@ -43,5 +43,9 @@
<p>Ještě nebylo hodnoceno</p>
{% endif %}
<form method=post><table>
{% csrf_token %}
{{ form }}
</table><input type=submit></form>
{% endblock %}

5
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/<int:problem>/<int:resitel>/', org_required(views.ReseniProblemuView.as_view()), name='odevzdavatko_reseni_resitele_k_problemu'),
path('temp/reseni/<int:pk>', org_required(views.DetailReseniView.as_view()), name='odevzdavatko_detail_reseni'),
path('temp/reseni/<int:pk>', 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())),
]

28
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í view jakožto funkce, takže u class-based views se 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()

28
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í

Loading…
Cancel
Save