86 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from http import HTTPStatus
 | |
| 
 | |
| from django.core.exceptions import ValidationError
 | |
| from django.db import transaction
 | |
| from django.forms import Form, CharField, IntegerField
 | |
| from django.views.generic import FormView
 | |
| 
 | |
| from tvorba.models import Cislo, Problem, Uloha, Tema
 | |
| from django.shortcuts import render, get_object_or_404
 | |
| 
 | |
| def problemView(request, pk):
 | |
| 	# Pokud problém neexistuje, hodíme obyčejnou 404
 | |
| 	# Taktéž v případě, že takový problém nemá být vidět
 | |
| 	problem = get_object_or_404(Problem, id=pk, stav__in=[Problem.STAV_ZADANY, Problem.STAV_VYRESENY])
 | |
| 	# Problém existuje, neumíme ho zobrazit, renderujeme nějakou haluz
 | |
| 	template = 'universal.html'
 | |
| 	ctx = {
 | |
| 		'raw_html': f'<h2>Obsah nelze zobrazit</h2><p>Požadovaný problém {problem.nazev} sice existuje, ale aktuálně jej nelze zobrazit. Omlouváme se za potíže</p>',
 | |
| 		}
 | |
| 	status_code = HTTPStatus.NOT_FOUND
 | |
| 	return render(request, template, context=ctx, status=status_code)
 | |
| 
 | |
| 
 | |
| # FIXME Tohle možná patří do forms.py
 | |
| # FIXME Chyby se ve formuláři zobrazují nějak divně
 | |
| class HromadnePridaniForm(Form):
 | |
| 	""" Formulář pro hromadné přidání úložek a problémů """
 | |
| 
 | |
| 	tema = CharField(label="Název tématu:")
 | |
| 	cislo = IntegerField(label="Číslo:", min_value=1)
 | |
| 	body = CharField(label="Počty bodů (0 pro problém) oddělené čárkami:")
 | |
| 
 | |
| 	def clean_tema(self):
 | |
| 		""" Kontrola, že `tema` je název právě jednoho tématu """
 | |
| 		if Tema.objects.filter(
 | |
| 				nazev__exact=self.cleaned_data['tema'],
 | |
| 				nadproblem=None).count() != 1:
 | |
| 			raise ValidationError("Špatný nebo nepřesně zadaný název témátka")
 | |
| 		return self.cleaned_data['tema']
 | |
| 
 | |
| 	def clean_body(self):
 | |
| 		""" Kontrola, že `body` je seznam čísel """
 | |
| 		try:
 | |
| 			list(map(float, self.cleaned_data["body"].split(",")))
 | |
| 		except ValueError:
 | |
| 			raise ValidationError("Špatný formát bodů")
 | |
| 		return self.cleaned_data['body']
 | |
| 
 | |
| 
 | |
| class HromadnePridaniView(FormView):
 | |
| 	""" View pro hromadné přidání úložek a problémů """
 | |
| 	form_class = HromadnePridaniForm
 | |
| 	template_name = "generic_form.html"
 | |
| 	success_url = 'hromadne_pridani'
 | |
| 
 | |
| 	def get_context_data(self, **kwargs):
 | |
| 		""" Přidání nadpisu stránky a url, kam se má poslat formulář. """
 | |
| 		context = super().get_context_data()
 | |
| 		context["nadpis"] = "Hromadné přidání úloh"
 | |
| 		context["form_url"] = "hromadne_pridani"
 | |
| 		return context
 | |
| 
 | |
| 	def form_valid(self, form):
 | |
| 		""" Upravený Pavlův skript na hromadné přidání úložek a problémů. """
 | |
| 		cd = form.cleaned_data
 | |
| 		tema = cd["tema"]
 | |
| 		cislo = cd["cislo"]
 | |
| 		body = list(map(float, cd["body"].split(",")))
 | |
| 
 | |
| 		t = Problem.objects.get(nazev__exact=tema, nadproblem=None)
 | |
| 		with transaction.atomic():
 | |
| 			pfx = f"{t.nazev}, "
 | |
| 
 | |
| 			for k, b in enumerate(body, 1):
 | |
| 				u = Uloha.objects.create(
 | |
| 					nadproblem=t,
 | |
| 					nazev=pfx + f"{'úloha' if b > 0 else 'problém'} {cislo}.{k}",
 | |
| 					autor=t.autor,
 | |
| 					garant=t.garant,
 | |
| 					max_body=b,
 | |
| 					cislo_zadani=Cislo.get(t.rocnik.rocnik, cislo),
 | |
| 					kod=k,
 | |
| 					stav=Problem.STAV_ZADANY,
 | |
| 				)
 | |
| 				u.opravovatele.set(t.opravovatele.all())
 | |
| 		return super().form_valid(form)
 |