""" 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: """ 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