Předělání sousových views #57
					 3 changed files with 87 additions and 78 deletions
				
			
		|  | @ -5,7 +5,7 @@ from django.contrib.staticfiles.finders import find | ||||||
| 
 | 
 | ||||||
| import csv | import csv | ||||||
| 
 | 
 | ||||||
| import various.views | import various.views.generic | ||||||
| from seminar.views import obalkyView | from seminar.views import obalkyView | ||||||
| 
 | 
 | ||||||
| from .models import Soustredeni, Soustredeni_Ucastnici | from .models import Soustredeni, Soustredeni_Ucastnici | ||||||
|  | @ -38,7 +38,10 @@ class KonkretniSoustredeniMixin: | ||||||
| 		self.soustredeni = get_object_or_404(Soustredeni, id=soustredeni_id) | 		self.soustredeni = get_object_or_404(Soustredeni, id=soustredeni_id) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class SoustredeniUcastniciBaseView(KonkretniSoustredeniMixin, various.views.NeprazdnyListView): | class SoustredeniUcastniciBaseView( | ||||||
|  | 	KonkretniSoustredeniMixin, | ||||||
|  | 	various.views.generic.NeprazdnyListView, | ||||||
|  | ): | ||||||
| 	""" | 	""" | ||||||
| 		Slouží jako ListView účastníků soustředění | 		Slouží jako ListView účastníků soustředění | ||||||
| 		+ háže inteligentní chybu při soustředění bez účastníků | 		+ háže inteligentní chybu při soustředění bez účastníků | ||||||
|  | @ -82,7 +85,10 @@ class SoustredeniUcastniciExportView(SoustredeniUcastniciBaseView): | ||||||
| 		return response | 		return response | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class SoustredeniStvrzenkyView(various.views.TeXResponseMixin, SoustredeniUcastniciBaseView): | class SoustredeniStvrzenkyView( | ||||||
|  | 	various.views.generic.TeXResponseMixin, | ||||||
|  | 	SoustredeniUcastniciBaseView, | ||||||
|  | ): | ||||||
| 	template_name = 'soustredeni/stvrzenky.tex' | 	template_name = 'soustredeni/stvrzenky.tex' | ||||||
| 	dalsi_potrebne_soubory = [find('images/logomm.pdf')] | 	dalsi_potrebne_soubory = [find('images/logomm.pdf')] | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,14 +1,5 @@ | ||||||
| import http | from django.http import HttpResponseForbidden | ||||||
| import tempfile |  | ||||||
| import shutil |  | ||||||
| import subprocess |  | ||||||
| 
 |  | ||||||
| from pathlib import Path |  | ||||||
| 
 |  | ||||||
| from django.http import HttpResponseForbidden, HttpResponse |  | ||||||
| from django.shortcuts import render | from django.shortcuts import render | ||||||
| from django.views import generic |  | ||||||
| from django.template.loader import render_to_string |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def csrf_error(request, reason=""): | def csrf_error(request, reason=""): | ||||||
|  | @ -18,68 +9,3 @@ def csrf_error(request, reason=""): | ||||||
| 		{"url": request.META.get("HTTP_REFERER", None), "reason": reason}, | 		{"url": request.META.get("HTTP_REFERER", None), "reason": reason}, | ||||||
| 		status=HttpResponseForbidden.status_code, | 		status=HttpResponseForbidden.status_code, | ||||||
| 	) | 	) | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class NeprazdnyListView(generic.ListView): |  | ||||||
| 	""" |  | ||||||
| 		Použití jako generic.ListView, jen při prázdném listu vyhodí M&M stránku |  | ||||||
| 		s titlem `self.if_prazdny_title` a textem `self.if_prazdny_text` |  | ||||||
| 		a způsob renderování (např. CSV) lze změnit přepsáním metody render. |  | ||||||
| 	""" |  | ||||||
| 	allow_empty = False |  | ||||||
| 	if_prazdny_title = "V seznamu nic není" |  | ||||||
| 	if_prazdny_text = "V seznamu nic není. Zkus to napravit v adminu, nebo se zeptej webařů." |  | ||||||
| 
 |  | ||||||
| 	# Skoro copy-paste generic.list.ListView.get, |  | ||||||
| 	# protože nemůžu chytat 404, neboť může nastat i v get_context_data |  | ||||||
| 	def get(self, request, *args, **kwargs): |  | ||||||
| 		self.object_list = self.get_queryset() |  | ||||||
| 
 |  | ||||||
| 		if self.get_paginate_by(self.object_list) is not None and hasattr( |  | ||||||
| 				self.object_list, "exists" |  | ||||||
| 		): |  | ||||||
| 			is_empty = not self.object_list.exists() |  | ||||||
| 		else: |  | ||||||
| 			is_empty = not self.object_list |  | ||||||
| 		if is_empty: |  | ||||||
| 			return render(request, 'universal.html', { |  | ||||||
| 					'title': self.if_prazdny_title, |  | ||||||
| 					'text': self.if_prazdny_text, |  | ||||||
| 				}, |  | ||||||
| 				status=http.HTTPStatus.NOT_FOUND, |  | ||||||
| 			) |  | ||||||
| 
 |  | ||||||
| 		return self.render(request, *args, **kwargs) |  | ||||||
| 
 |  | ||||||
| 	# Tohle jsem vyčlenil, aby šlo generovat i něco jiného než template |  | ||||||
| 	def render(self, request, *args, **kwargs): |  | ||||||
| 		context = self.get_context_data() |  | ||||||
| 		return self.render_to_response(context) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class TeXResponseMixin: |  | ||||||
| 	""" |  | ||||||
| 		Mixin pro TemplateView, aby výsledek projel TeXem a vrátil rovnou PDF. |  | ||||||
| 		Obrázky a jiné soubory lze přidat nastavením `dalsi_potrebne_soubory` |  | ||||||
| 		(např. na `[django.contrib.staticfiles.finders.find('bla')]`, |  | ||||||
| 		nebo jiný seznam absolutních cest). |  | ||||||
| 	""" |  | ||||||
| 	dalsi_potrebne_soubory = [] |  | ||||||
| 	tex = "pdflatex" |  | ||||||
| 
 |  | ||||||
| 	def render_to_response(self, context, **response_kwargs): |  | ||||||
| 		zdrojak = render_to_string(self.get_template_names(), context) |  | ||||||
| 
 |  | ||||||
| 		with tempfile.TemporaryDirectory() as tempdirfn: |  | ||||||
| 			tempdir = Path(tempdirfn) |  | ||||||
| 			with open(tempdir / "main.tex", "w") as texfile: |  | ||||||
| 				texfile.write(zdrojak) |  | ||||||
| 			for file in self.dalsi_potrebne_soubory: |  | ||||||
| 				shutil.copy(file, tempdir) |  | ||||||
| 			subprocess.call([self.tex, "main.tex"], cwd=tempdir, stdout=subprocess.DEVNULL) |  | ||||||
| 
 |  | ||||||
| 			with open(tempdir / "main.pdf", "rb") as pdffile: |  | ||||||
| 				response = HttpResponse(pdffile.read(), content_type='application/pdf', **response_kwargs) |  | ||||||
| 		return response |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|  |  | ||||||
							
								
								
									
										77
									
								
								various/views/generic.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								various/views/generic.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,77 @@ | ||||||
|  | """ | ||||||
|  | Stejně jako je `django.views.generic` jsou zde generické Views | ||||||
|  | a pár mixinů, které upravují chování Views. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import http | ||||||
|  | import shutil | ||||||
|  | import subprocess | ||||||
|  | import tempfile | ||||||
|  | 
 | ||||||
|  | from pathlib import Path | ||||||
|  | 
 | ||||||
|  | from django.http import HttpResponse | ||||||
|  | from django.shortcuts import render | ||||||
|  | from django.template.loader import render_to_string | ||||||
|  | from django.views import generic | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class NeprazdnyListView(generic.ListView): | ||||||
|  | 	""" | ||||||
|  | 		Použití jako generic.ListView, jen při prázdném listu vyhodí M&M stránku | ||||||
|  | 		s titlem `self.if_prazdny_title` a textem `self.if_prazdny_text` | ||||||
|  | 		a způsob renderování (např. CSV) lze změnit přepsáním metody render. | ||||||
|  | 	""" | ||||||
|  | 	allow_empty = False | ||||||
|  | 	if_prazdny_title = "V seznamu nic není" | ||||||
|  | 	if_prazdny_text = "V seznamu nic není. Zkus to napravit v adminu, nebo se zeptej webařů." | ||||||
|  | 
 | ||||||
|  | 	# Skoro copy-paste generic.list.ListView.get, | ||||||
|  | 	# protože nemůžu chytat 404, neboť může nastat i v get_context_data | ||||||
|  | 	def get(self, request, *args, **kwargs): | ||||||
|  | 		self.object_list = self.get_queryset() | ||||||
|  | 
 | ||||||
|  | 		if self.get_paginate_by(self.object_list) is not None and hasattr( | ||||||
|  | 				self.object_list, "exists" | ||||||
|  | 		): | ||||||
|  | 			is_empty = not self.object_list.exists() | ||||||
|  | 		else: | ||||||
|  | 			is_empty = not self.object_list | ||||||
|  | 		if is_empty: | ||||||
|  | 			return render(request, 'universal.html', { | ||||||
|  | 				'title': self.if_prazdny_title, | ||||||
|  | 				'text': self.if_prazdny_text, | ||||||
|  | 			}, status=http.HTTPStatus.NOT_FOUND) | ||||||
|  | 
 | ||||||
|  | 		return self.render(request, *args, **kwargs) | ||||||
|  | 
 | ||||||
|  | 	# Tohle jsem vyčlenil, aby šlo generovat i něco jiného než template | ||||||
|  | 	def render(self, request, *args, **kwargs): | ||||||
|  | 		context = self.get_context_data() | ||||||
|  | 		return self.render_to_response(context) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class TeXResponseMixin: | ||||||
|  | 	""" | ||||||
| 
				
				zelvuska marked this conversation as resolved
				
					
					
						Outdated
					
				
			 | |||||||
|  | 		Mixin pro TemplateView, aby výsledek projel TeXem a vrátil rovnou PDF. | ||||||
|  | 		Obrázky a jiné soubory lze přidat nastavením `dalsi_potrebne_soubory` | ||||||
|  | 		(např. na `[django.contrib.staticfiles.finders.find('bla')]`, | ||||||
|  | 		nebo jiný seznam absolutních cest). | ||||||
|  | 	""" | ||||||
|  | 	dalsi_potrebne_soubory = [] | ||||||
|  | 	tex = "pdflatex" | ||||||
|  | 
 | ||||||
|  | 	def render_to_response(self, context, **response_kwargs): | ||||||
|  | 		zdrojak = render_to_string(self.get_template_names(), context) | ||||||
|  | 
 | ||||||
|  | 		with tempfile.TemporaryDirectory() as tempdirfn: | ||||||
|  | 			tempdir = Path(tempdirfn) | ||||||
|  | 			with open(tempdir / "main.tex", "w") as texfile: | ||||||
|  | 				texfile.write(zdrojak) | ||||||
|  | 			for file in self.dalsi_potrebne_soubory: | ||||||
|  | 				shutil.copy(file, tempdir) | ||||||
|  | 			subprocess.call([self.tex, "main.tex"], cwd=tempdir, stdout=subprocess.DEVNULL) | ||||||
|  | 
 | ||||||
|  | 			with open(tempdir / "main.pdf", "rb") as pdffile: | ||||||
|  | 				response = HttpResponse(pdffile.read(), content_type='application/pdf', **response_kwargs) | ||||||
|  | 		return response | ||||||
		Loading…
	
		Reference in a new issue
	
	
Tohle je naše věc, nebo něco co využívá
ListViewinterně?