WIP: odevzdávátkové formsety
This commit is contained in:
		
							parent
							
								
									8c64fb5a24
								
							
						
					
					
						commit
						658f2a53c6
					
				
					 5 changed files with 69 additions and 6 deletions
				
			
		|  | @ -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ší? | ||||
| 				) | ||||
| 			} | ||||
| 		) | ||||
|  |  | |||
|  | @ -43,5 +43,9 @@ | |||
| <p>Ještě nebylo hodnoceno</p> | ||||
| {% endif %} | ||||
| 
 | ||||
| <form method=post><table> | ||||
| {% csrf_token %} | ||||
| {{ form }} | ||||
| </table><input type=submit></form> | ||||
| 
 | ||||
| {% endblock %} | ||||
|  |  | |||
|  | @ -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())), | ||||
| 
 | ||||
| ] | ||||
|  |  | |||
|  | @ -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() | ||||
| 
 | ||||
|  |  | |||
|  | @ -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…
	
		Reference in a new issue
	
	 Pavel "LEdoian" Turinsky
						Pavel "LEdoian" Turinsky