První dokumentace
This commit is contained in:
parent
cbf17f7709
commit
5113a7adab
42 changed files with 479 additions and 8 deletions
|
@ -1,3 +1,6 @@
|
|||
"""
|
||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
||||
"""
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
"""
|
||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||
|
||||
- ``aesop-export/mam-rocnik-<int:prvni_rok>.csv`` (seminar_export_rocnik) :class:`~aesop.views.ExportRocnikView`
|
||||
- ``aesop-export/mam-sous-<str:datum_zacatku>.csv`` (seminar_export_sous) :class:`~aesop.views.ExportSousView`
|
||||
- ``aesop-export/index.csv`` (seminar_export_index) :class:`~aesop.views.ExportIndexView`
|
||||
"""
|
||||
from django.urls import path
|
||||
from aesop import views
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
"""
|
||||
Soubor sloužící k deklaraci jednotlivých „views“ (nejčastěji funkce beroucí request
|
||||
a vracející :func:`django.shortcuts.render` respektive nějakou response, nebo
|
||||
třídy většinou rozšiřující nějakou třídu z :mod:`django.views.generic`)
|
||||
"""
|
||||
import django
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.http import HttpResponse
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
"""
|
||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
||||
"""
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
|
12
api/urls.py
12
api/urls.py
|
@ -1,3 +1,15 @@
|
|||
"""
|
||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||
|
||||
- ``api/expor/skoly/`` (export_skoly) :func:`~api.views.exports.exportSkolView`
|
||||
- ``api/autocomplete/skola/`` (autocomplete_skola) :class:`~api.views.autocomplete.SkolaAutocomplete`
|
||||
- ``api/autocomplete/resitel/`` (autocomplete_resitel) :class:`~api.views.autocomplete.ResitelAutocomplete`
|
||||
- ``api/autocomplete/problem/odevzdatelny`` (autocomplete_problem_odevzdatelny) :class:`~api.views.autocomplete.OdevzdatelnyProblemAutocomplete`
|
||||
|
||||
Na autocomplete v3 čeká:
|
||||
|
||||
- ``autocomplete/organizatori/`` (seminar_autocomplete_organizator) :class:`~api.views.autocomplete.OrganizatorAutocomplete`
|
||||
"""
|
||||
from django.urls import path
|
||||
from . import views
|
||||
from seminar.utils import org_required
|
||||
|
|
|
@ -1,2 +1,7 @@
|
|||
"""
|
||||
Soubory sloužící k deklaraci jednotlivých „views“ (nejčastěji funkce beroucí request
|
||||
a vracející :func:`django.shortcuts.render` respektive nějakou response, nebo
|
||||
třídy většinou rozšiřující nějakou třídu z :mod:`django.views.generic`)
|
||||
"""
|
||||
from .autocomplete import *
|
||||
from .exports import *
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
"""
|
||||
Views k :mod:`dal.autocomplete` pro vyhledávání objektů nějaké třídy v databázi.
|
||||
"""
|
||||
from dal import autocomplete
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.db.models import Q
|
||||
|
@ -7,6 +10,7 @@ from .helpers import LoginRequiredAjaxMixin
|
|||
|
||||
# TODO filosofie - zkratky, jak v databázi, tak ve vyhledávání (SPŠE, GASOŠ, Kpt., soukr)
|
||||
class SkolaAutocomplete(autocomplete.Select2QuerySetView):
|
||||
""" View k :mod:`dal.autocomplete` pro vyhledávání škol hlavně při registraci. """
|
||||
def get_queryset(self):
|
||||
# Don't forget to filter out results depending on the visitor !
|
||||
qs = m.Skola.objects.all()
|
||||
|
@ -25,6 +29,7 @@ class SkolaAutocomplete(autocomplete.Select2QuerySetView):
|
|||
return qs
|
||||
|
||||
class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetView):
|
||||
""" View k :mod:`dal.autocomplete` pro vyhledávání řešitelů především v odevzdávátku. """
|
||||
def get_queryset(self):
|
||||
qs = m.Resitel.objects.all()
|
||||
if self.q:
|
||||
|
@ -40,6 +45,7 @@ class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetVie
|
|||
return qs
|
||||
|
||||
class OdevzdatelnyProblemAutocomplete(autocomplete.Select2QuerySetView):
|
||||
""" View k :mod:`dal.autocomplete` pro vyhledávání problémů především v odevzdávátku. """
|
||||
def get_queryset(self):
|
||||
nastaveni = get_object_or_404(m.Nastaveni)
|
||||
rocnik = nastaveni.aktualni_rocnik
|
||||
|
|
|
@ -2,6 +2,9 @@ import seminar.models as m
|
|||
from django.core import serializers as ser
|
||||
from django.http import HttpResponse
|
||||
def exportSkolView(request):
|
||||
"""
|
||||
„view“, který vrací json se seznamem škol, u kterých je uvedeno: 'id', 'izo', 'nazev', 'kratky_nazev', 'ulice', 'mesto', 'psc', 'stat', 'je_zs', 'je_ss'
|
||||
"""
|
||||
# Některé fieldy nechceme: Kontaktní osoby, AESOP ID, org poznámky.
|
||||
fields = ('id', 'izo', 'nazev', 'kratky_nazev', 'ulice', 'mesto', 'psc', 'stat', 'je_zs', 'je_ss')
|
||||
# TODO: Použít JSONL, aby protistrana mohla číst po řádkách a nesežralo to tunu paměti úplně hned
|
||||
|
|
|
@ -2,6 +2,9 @@ from django.http import JsonResponse
|
|||
|
||||
|
||||
class LoginRequiredAjaxMixin(object):
|
||||
"""
|
||||
Objekt přidávající povinnost být přihlášený k zobrazení daného view.
|
||||
"""
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
#if request.is_ajax() and not request.user.is_authenticated: # Pokud to otevřu jako stránku, tak se omezení neuplatní, takže to asi nechceme
|
||||
if not request.user.is_authenticated:
|
||||
|
|
92
docs/dalsi_soubory.rst
Normal file
92
docs/dalsi_soubory.rst
Normal file
|
@ -0,0 +1,92 @@
|
|||
Další soubory/složky v kořenovém adresáři
|
||||
=========================================
|
||||
|
||||
media
|
||||
-----
|
||||
Složka, kam django nahrává soubory „jako by je nahrávalo do databáze“.
|
||||
|
||||
static
|
||||
------
|
||||
Složka, kam django nakopíruje všechno ze složek static a pak na to z templatů / kódu jde ukazovat pomocí ``static``.
|
||||
|
||||
_git_hooks
|
||||
----------
|
||||
Hooky do gitu pro kontrolu Pythoního stylu. Především ``flake8``.
|
||||
|
||||
Zbylo tu z minulosti mamwebu.
|
||||
|
||||
data
|
||||
----
|
||||
Obsahuje data, která patří do databáze, ale jsou přímo součástí webu jako
|
||||
takového. Aktuálně jsou to statické stránky, meníčko a rozložení obrázků
|
||||
v pozadí meníčka.
|
||||
|
||||
Generuje se za pomocí::
|
||||
|
||||
./manage.py dumpdata flatpages > data/flat_new.json
|
||||
./fix_json.py data/flat_new.json data/flat.json
|
||||
|
||||
nebo (v případě meníčka)::
|
||||
|
||||
./manage.py dumpdata sitetree --natrual-foreign > data/sitetree_new.json
|
||||
./fix_json.py data/sitetree_new.json data/sitetree.json
|
||||
|
||||
deploy_v2
|
||||
---------
|
||||
Věci, které byly potřeba při nasazování nového (2021) webu.
|
||||
|
||||
docs
|
||||
----
|
||||
Zde je dokumentace webu. Viz :ref:`Sphinx na našem webu`.
|
||||
|
||||
setup
|
||||
-----
|
||||
Tato složka obsahuje různé konfiguráky potřebné k rozběhnutí webu na serveru.
|
||||
|
||||
vue_frontend
|
||||
------------
|
||||
Obsahuje první pokusy o editory treenodů ve vue.
|
||||
|
||||
.gitignore
|
||||
----------
|
||||
Klasické `.gitignore`_
|
||||
|
||||
.. _.gitignore: https://git-scm.com/docs/gitignore
|
||||
|
||||
checklinks.sh
|
||||
-------------
|
||||
„Týrací“ skript na kontrolu, že nic, kam se lze proklikat na webu, nehází chybu.
|
||||
|
||||
constraints.txt
|
||||
---------------
|
||||
Obsahuje omezení na :ref:`requirements.txt`.
|
||||
|
||||
convert_spaces_to_tabs.sh
|
||||
-------------------------
|
||||
Skript na změnu odsazování.
|
||||
|
||||
db-local.sqlite3
|
||||
----------------
|
||||
Lokální databáze (na serveru není).
|
||||
|
||||
diff_db_backup.sh
|
||||
-----------------
|
||||
Nevím. Typoval bych skript na diff záloh (resp. dumpů) databáze.
|
||||
|
||||
Makefile
|
||||
--------
|
||||
Klasické `Makefile`_. Obsahuje například vytvoření virtual_env, instalaci a nasazování webu.
|
||||
|
||||
.. _Makefile: https://www.gnu.org/software/make/manual/make.html
|
||||
|
||||
manage.py
|
||||
---------
|
||||
Základní soubor djanga.
|
||||
|
||||
README.md
|
||||
---------
|
||||
Většina je spíš zbytek po bývalých webařích.
|
||||
|
||||
requirements.txt
|
||||
----------------
|
||||
Seznam balíčků, které jsou potřeba pro běh mamwebu. (Cílem je vytvoření virtualenvu se všemi těmito balíčky, např. pomocí daného příkazu v :ref:`Makefile`.)
|
55
docs/default_doc.rst
Normal file
55
docs/default_doc.rst
Normal file
|
@ -0,0 +1,55 @@
|
|||
Defaultní dokumentace speciálních souborů
|
||||
=========================================
|
||||
|
||||
Drobná nápověda k běžným django souborům. (Do nich jsem to vkládal copy-paste.)
|
||||
|
||||
admin.py
|
||||
--------
|
||||
Soubor sloužící k definici toho, co bude v adminu. Většinou pouhým zavoláním
|
||||
funkce :func:`django.contrib.admin.site.register`, v případě, že chceme něco
|
||||
upravit, tak jako třída rozšiřující :class:`django.contrib.admin.ModelAdmin`
|
||||
s dekorátorem :func:`django.contrib.admin.register`.
|
||||
|
||||
Zde se definuje admin pro:
|
||||
|
||||
apps.py
|
||||
-------
|
||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
||||
|
||||
forms.py
|
||||
--------
|
||||
Formuláře (:class:`django.forms.Form`) umožňují jednoduchou tvorbu formulářů,
|
||||
které lze pak jednoduše dát do frontendu i zpracovat na backendu.
|
||||
|
||||
Pro přidání políčka do formuláře je potřeba
|
||||
- mít v modelu tu položku, kterou chci upravovat
|
||||
- přidat do views (prihlaskaView, resitelEditView)
|
||||
- přidat do forms
|
||||
- includovat do html
|
||||
|
||||
models.py
|
||||
---------
|
||||
Tento soubor slouží k definici databázového modelu.
|
||||
|
||||
Třídy rozšiřují většinou :class:`django.db.models.Model` a jejich atributy jsou
|
||||
většinou sloupce v databázi (tj. nastaví se na hodnotu něčeho z :mod:`django.db.models`).
|
||||
Na výběr jsou:
|
||||
|
||||
- :class:`django.db.models.TextField`
|
||||
- :class:`django.db.models.ForeignKey`
|
||||
- :class:`django.db.models.DateField`
|
||||
- :class:`django.db.models.DateTimeField`
|
||||
- :class:`django.db.models.ImageField`
|
||||
- :class:`django.db.models.CharField`
|
||||
|
||||
testutils.py
|
||||
------------
|
||||
Soubor sloužící ke generování testdat.
|
||||
|
||||
urls.py
|
||||
-------
|
||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||
|
||||
views.py
|
||||
--------
|
||||
|
|
@ -12,6 +12,7 @@ Vítejte v dokumentaci M&Mího webu!
|
|||
|
||||
vyvoj
|
||||
sphinx
|
||||
dalsi_soubory
|
||||
modules/modules
|
||||
|
||||
|
||||
|
|
|
@ -6,9 +6,10 @@ Dokumentace se zkompiluje příkazem ``make html`` ve složce ``doc``.
|
|||
Složka ``modules`` je automaticiky generována a přegenerovávána. (**Nic v ní neupravovat!**)
|
||||
Jinak všechny rst, co jsou ve složce ``doc`` a jejích podsložkách nezačínajících podtržítkem, budou v dokumentaci a to je přesně to, co editovat pro změnu dokumentace (kromě dokumentace přímo v Pythonu).
|
||||
|
||||
Sphinx se píše v rst: `Návod na syntaxi rst`_
|
||||
Sphinx se píše v rst: `Návod na syntaxi rst`_ `Cheat sheet`_
|
||||
|
||||
.. _Návod na syntaxi rst: https://sphinx-tutorial.readthedocs.io/step-1/#sections
|
||||
.. _Cheat sheet: https://sphinx-tutorial.readthedocs.io/cheatsheet/
|
||||
|
||||
Problém
|
||||
-------
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
# coding: utf-8
|
||||
"""
|
||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||
|
||||
- ``<int:pk>/`` :func:`~galerie.views.nahled`
|
||||
- ``<int:pk>/<int:fotka>/`` :func:`~galerie.views.detail`
|
||||
- ``<int:galerie>/new/`` :func:`~galerie.views.new_galerie`
|
||||
- ``<int:galerie>/plus/<int:subgalerie>/`` :func:`~galerie.views.plus_galerie`
|
||||
- ``<int:galerie>/minus/<int:subgalerie>/`` :func:`~galerie.views.minus_galerie`
|
||||
"""
|
||||
from django.urls import path
|
||||
from seminar.utils import org_required
|
||||
from . import views
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
"""
|
||||
Aplikace umožňující „na uživatelské úrovni“ měnit obrázek v pozadí meníčka.
|
||||
|
||||
Umožňuje uložit obrázek a následně popsat, na kterých stránkách (podle url)
|
||||
a v který čas (den/noc) se má zobrazovat.
|
||||
"""
|
|
@ -1,9 +1,24 @@
|
|||
"""
|
||||
Soubor sloužící k definici toho, co bude v adminu. Většinou pouhým zavoláním
|
||||
funkce :func:`django.contrib.admin.site.register`, v případě, že chceme něco
|
||||
upravit, tak jako třída rozšiřující :class:`django.contrib.admin.ModelAdmin`
|
||||
s dekorátorem :func:`django.contrib.admin.register`.
|
||||
|
||||
Zde se definuje admin pro:
|
||||
|
||||
- :class:`~header_fotky.models.FotkaHeader`
|
||||
- :class:`~header_fotky.models.FotkaUrlVazba`
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.contrib.admin import ModelAdmin
|
||||
import header_fotky.models as m
|
||||
|
||||
|
||||
class FotkaPozadiAdmin(ModelAdmin):
|
||||
"""
|
||||
Nastaví čas vložení (:attr:`~header_fotky.models.FotkaHeader.cas`) jako
|
||||
readonly = neměnitelný
|
||||
"""
|
||||
readonly_fields = ['cas']
|
||||
|
||||
admin.site.register(m.FotkaHeader, FotkaPozadiAdmin)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
"""
|
||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
||||
"""
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
|
||||
"""
|
||||
Context processory lze přidat do djanga v :mod:`~mamweb.settings` a dělají to,
|
||||
že do contextu (tj. to, z čeho se např. berou proměnné v templatech) libovolné
|
||||
stránky přidají další věci.
|
||||
"""
|
||||
from datetime import datetime, date
|
||||
import random
|
||||
|
||||
|
@ -8,7 +12,15 @@ from header_fotky.models import FotkaUrlVazba
|
|||
|
||||
|
||||
def vzhled(request):
|
||||
''' Podle casu prida do templatu, zdali je nebo neni noc '''
|
||||
"""
|
||||
Podle času přidá do contextu, zdali je nebo není noc. Dále podle dení
|
||||
doby a url přidá do contextu správnou fotku.
|
||||
|
||||
url adresu nejprve vyzkouší celou, pak postupně odřezává věci za
|
||||
lomítkem, dokud nenajde url, pro kterou existuje alespoň jedna fotka.
|
||||
Z fotek pro toto url zkusí vybrat tu ve správné denní době a až poté
|
||||
libovolnou. (Z více možných fotek pro 1 url a 1 dobu vybírá náhodně.)
|
||||
"""
|
||||
hodin = datetime.now().hour
|
||||
if (hodin <= 6) or (hodin >= 20):
|
||||
noc = True
|
||||
|
|
|
@ -1,9 +1,24 @@
|
|||
"""
|
||||
Tento soubor slouží k definici databázového modelu.
|
||||
|
||||
Třídy rozšiřují většinou :class:`django.db.models.Model` a jejich atributy jsou
|
||||
většinou sloupce v databázi (tj. nastaví se na hodnotu něčeho z :mod:`django.db.models`).
|
||||
Na výběr jsou:
|
||||
|
||||
- :class:`django.db.models.TextField`
|
||||
- :class:`django.db.models.ForeignKey`
|
||||
- :class:`django.db.models.DateField`
|
||||
- :class:`django.db.models.DateTimeField`
|
||||
- :class:`django.db.models.ImageField`
|
||||
- :class:`django.db.models.CharField`
|
||||
"""
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
class FotkaHeader(models.Model):
|
||||
""" fotka pro :mod:`fotka_header`, konkrétně :class:`~fotka_header.models.FotkaUrlVazba` """
|
||||
class Meta:
|
||||
ordering = ['-cas']
|
||||
db_table = 'fotky_header'
|
||||
|
@ -11,27 +26,34 @@ class FotkaHeader(models.Model):
|
|||
verbose_name_plural = u'fotky do pozadí menu'
|
||||
|
||||
cas = models.DateTimeField(u'čas vložení fotky', default=timezone.now, help_text='Čas vložení fotky')
|
||||
""" čas vložení fotky """
|
||||
|
||||
nazev = models.CharField(
|
||||
u'název fotky', null=False, blank=False, unique=True, primary_key=True,
|
||||
max_length=50, help_text='Název např. archiv_noc'
|
||||
)
|
||||
""" jméno fotky na webu """
|
||||
|
||||
fotka = models.ImageField(upload_to='header', null=False, blank=False)
|
||||
""" soubor fotky (Nahrává se automaticky do složky ``media``.) """
|
||||
|
||||
def __str__(self):
|
||||
return self.nazev
|
||||
|
||||
def clean(self):
|
||||
""" kontroluje, zda sedí poměr stran """
|
||||
if not self.fotka:
|
||||
raise ValidationError("Chybí obrázek")
|
||||
""" Kontroluje, zda sedí poměr stran """
|
||||
if abs(self.fotka.width - (self.fotka.height * 970 / 350)) > 2:
|
||||
raise ValidationError("Obrázek by měl mít rozměry 970w na 350h, nebo alespoň podobný poměr stran.")
|
||||
super().clean()
|
||||
|
||||
|
||||
class FotkaUrlVazba(models.Model):
|
||||
"""
|
||||
spojení :class:`~fotka_header.models.FotkaHeader` a url
|
||||
(resp. „prefixu“ url), na které má být zobrazována
|
||||
"""
|
||||
class Meta:
|
||||
ordering = ['url']
|
||||
db_table = 'fotky_url_vazby'
|
||||
|
@ -42,11 +64,13 @@ class FotkaUrlVazba(models.Model):
|
|||
u'URL', blank=True, null=False, max_length=100,
|
||||
help_text='url prefix stránek např: /archiv/ nebo /'
|
||||
)
|
||||
""" url prefix stránek, kde má být fotka zobrazena, např: /archiv/ nebo / """
|
||||
|
||||
fotka = models.ForeignKey(
|
||||
FotkaHeader, blank=False, null=False, verbose_name='fotka',
|
||||
on_delete=models.CASCADE
|
||||
)
|
||||
""" :class:`~fotka_header.models.FotkaHeader`, která má být zobrazována """
|
||||
|
||||
DOBA_DEN = 'den'
|
||||
DOBA_NOC = 'noc'
|
||||
|
@ -57,9 +81,11 @@ class FotkaUrlVazba(models.Model):
|
|||
(DOBA_OBOJI, 'Zobrazovat pořád')]
|
||||
|
||||
denni_doba = models.CharField('denní doba', max_length=16, choices=DOBA_CHOICES, blank=False, default=DOBA_OBOJI)
|
||||
""" dení doba, kdy tam má být zobrazována """
|
||||
|
||||
def __str__(self):
|
||||
return self.url
|
||||
|
||||
def url_fotky(self):
|
||||
""" vrací url fotky (tj. url, kde reálně získám soubor fotky) """
|
||||
return self.fotka.fotka.url
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
"""
|
||||
Seznam pdf k opravě a `opraf`_ v djangu místo PHP.
|
||||
|
||||
.. _opraf: https://github.com/vitstradal/opraf
|
||||
"""
|
|
@ -1,3 +1,13 @@
|
|||
"""
|
||||
Soubor sloužící k definici toho, co bude v adminu. Většinou pouhým zavoláním
|
||||
funkce :func:`django.contrib.admin.site.register`, v případě, že chceme něco
|
||||
upravit, tak jako třída rozšiřující :class:`django.contrib.admin.ModelAdmin`
|
||||
s dekorátorem :func:`django.contrib.admin.register`.
|
||||
|
||||
Zde se definuje admin pro:
|
||||
|
||||
- :class:`korektury.models.KorekturovanePDF`
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from reversion.admin import VersionAdmin
|
||||
from korektury.models import KorekturovanePDF
|
||||
|
@ -7,10 +17,18 @@ from django.urls import reverse
|
|||
|
||||
# Register your models here.
|
||||
class KorekturovanePDFAdmin(VersionAdmin):
|
||||
"""
|
||||
nastaví čas vložení (:attr:`~koretkury.models.KorekturovanePDF.cas`) a počet
|
||||
stran (:attr:`~koretkury.models.KorekturovanePDF.stran`) jako readonly =
|
||||
neměnitelný
|
||||
|
||||
Při prvním uložení pošle e-mail.
|
||||
"""
|
||||
|
||||
readonly_fields = ['cas', 'stran']
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
""" Nevím, proč to tu je - Jidáš """
|
||||
if obj:
|
||||
return self.readonly_fields + ['pdf']
|
||||
return self.readonly_fields
|
||||
|
@ -26,6 +44,9 @@ class KorekturovanePDFAdmin(VersionAdmin):
|
|||
search_fields = []
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
"""
|
||||
Pokud je soubor nový a má se poslat e-mail, tak pošle e-mail o novém pdf.
|
||||
"""
|
||||
super().save_model(request, obj, form, change)
|
||||
if not change and obj.poslat_mail: # Je nový a má se poslat mail
|
||||
odkaz = request.build_absolute_uri(reverse('korektury', kwargs={'pdf': obj.id}))
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
"""
|
||||
Formuláře (:class:`django.forms.Form`) umožňují jednoduchou tvorbu formulářů,
|
||||
které lze pak jednoduše dát do frontendu i zpracovat na backendu.
|
||||
|
||||
Pro přidání políčka do formuláře je potřeba
|
||||
- mít v modelu tu položku, kterou chci upravovat
|
||||
- přidat do views (prihlaskaView, resitelEditView)
|
||||
- přidat do forms
|
||||
- includovat do html
|
||||
"""
|
||||
from django import forms
|
||||
|
||||
class OpravaForm(forms.Form):
|
||||
""" formulář k přidání opravy (:class:`korektury.models.Oprava`) """
|
||||
text = forms.CharField(max_length=256)
|
||||
autor = forms.CharField(max_length=20)
|
||||
x = forms.IntegerField()
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Tento soubor slouží k definici databázového modelu.
|
||||
|
||||
Třídy rozšiřují většinou :class:`django.db.models.Model` a jejich atributy jsou
|
||||
většinou sloupce v databázi (tj. nastaví se na hodnotu něčeho z :mod:`django.db.models`).
|
||||
Na výběr jsou:
|
||||
|
||||
- :class:`django.db.models.TextField`
|
||||
- :class:`django.db.models.ForeignKey`
|
||||
- :class:`django.db.models.DateField`
|
||||
- :class:`django.db.models.DateTimeField`
|
||||
- :class:`django.db.models.ImageField`
|
||||
- :class:`django.db.models.CharField`
|
||||
"""
|
||||
import os
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
@ -16,6 +29,7 @@ from unidecode import unidecode
|
|||
|
||||
|
||||
def generate_filename(self, filename):
|
||||
""" vyrobí jméno souboru podle původního jména a času nahrátí """
|
||||
clean = get_valid_filename(
|
||||
unidecode(
|
||||
filename.replace('/', '-').replace('\0', '').replace(":", "_")
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
"""
|
||||
Soubor sloužící ke generování testdat.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
from shutil import copyfile, rmtree
|
||||
|
@ -11,6 +14,7 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
@transaction.atomic
|
||||
def create_test_pdf(rnd, organizatori):
|
||||
""" Vyrobí testovací pdf ke korekturování. Nevyrábí korektury! """
|
||||
logger.info('Vyrábím testovací pdf ke korekturovani')
|
||||
try:
|
||||
testpdfs = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'testpdfs')
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
"""
|
||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||
|
||||
- ``korektury/`` (korektury_list) :class:`~korektury.views.KorekturySeskupeneListView`
|
||||
- ``korektury/neseskupene/`` (korektury_neseskupene_list) :class:`~korektury.views.KorekturyAktualniListView`
|
||||
- ``korektury/zastarale/`` (korektury_stare_list) :class:`~korektury.views.KorekturyZastaraleListView`
|
||||
- ``korektury/<int:pdf>/`` (korektury) :class:`~korektury.views.KorekturyView`
|
||||
"""
|
||||
from django.urls import path
|
||||
from seminar.utils import org_required
|
||||
from . import views
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Soubor sloužící k deklaraci jednotlivých „views“ (nejčastěji funkce beroucí request
|
||||
a vracející :func:`django.shortcuts.render` respektive nějakou response, nebo
|
||||
třídy většinou rozšiřující nějakou třídu z :mod:`django.views.generic`)
|
||||
"""
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.views import generic
|
||||
from django.utils.translation import ugettext as _
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
"""
|
||||
Soubor sloužící k úpravě základních vlastností adminu. Zde se do adminu přidává
|
||||
CKEditor, nastavuje české řazení v adminu a preference (zobrazuje se v seznamu
|
||||
jako první) adminu k Semináři.
|
||||
"""
|
||||
import locale
|
||||
from django.contrib import admin
|
||||
from django.contrib.admin import AdminSite
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
"""
|
||||
Soubor sloužící jako základní „router“, tj. zde se includují veškeré ostatní urls:
|
||||
|
||||
- ``admin/`` :mod:`django.contrib.admin.site.urls`
|
||||
- ``ckeditor/`` :mod:`ckeditor_uploader.urls`
|
||||
- :mod:`seminar.urls`
|
||||
- :mod:`odevzdavatko.urls`
|
||||
- :mod:`korektury.urls`
|
||||
- :mod:`prednasky.urls`
|
||||
- :mod:`soustredeni.urls`
|
||||
- :mod:`personalni.urls`
|
||||
- :mod:`various.autentizace.urls`
|
||||
- :mod:`api.urls`
|
||||
- :mod:`treenode.urls`
|
||||
- :mod:`aesop.urls`
|
||||
- ``comments_dj/`` :mod:`django_comments.urls`
|
||||
"""
|
||||
from django.urls import path, include
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
from django.contrib import admin
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
"""
|
||||
Soubor sloužící k definici toho, co bude v adminu. Většinou pouhým zavoláním
|
||||
funkce :func:`django.contrib.admin.site.register`, v případě, že chceme něco
|
||||
upravit, tak jako třída rozšiřující :class:`django.contrib.admin.ModelAdmin`
|
||||
s dekorátorem :func:`django.contrib.admin.register`.
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django_reverse_admin import ReverseModelAdmin
|
||||
import seminar.models as m
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
"""
|
||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
||||
"""
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
"""
|
||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||
|
||||
- ``org/add_solution`` (seminar_vloz_reseni) :class:`~odevzdavatko.views.PosliReseniView`
|
||||
- ``resitel/nahraj_reseni`` (seminar_nahraj_reseni) :class:`~odevzdavatko.views.NahrajReseniView`
|
||||
- ``resitel/odevzdana_reseni/`` (seminar_resitel_odevzdana_reseni) :class:`~odevzdavatko.views.PrehledOdevzdanychReseni`
|
||||
- ``org/reseni/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
||||
- ``org/reseni/rocnik/<int:rocnik>/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
||||
- ``org/reseni/<int:problem>/<int:resitel>/`` (odevzdavatko_reseni_resitele_k_problemu) :class:`~odevzdavatko.views.ReseniProblemuView`
|
||||
- ``org/reseni/<int:pk>/`` (odevzdavatko_detail_reseni) :func:`~seminar.utils.viewMethodSwitch` + :class:`~odevzdavatko.views.DetailReseniView` + :func:`~odevzdavatko.views.hodnoceniReseniView`
|
||||
- ``org/reseni/all`` :class:`~odevzdavatko.views.SeznamReseniView`
|
||||
- ``org/reseni/akt`` :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
||||
- ``resitel/reseni/<int:pk>`` (odevzdavatko_resitel_reseni) :class:`~odevzdavatko.views.ResitelReseniView`
|
||||
"""
|
||||
from django.urls import path
|
||||
|
||||
from seminar.utils import org_required, resitel_required, viewMethodSwitch, \
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
"""
|
||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
||||
"""
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
"""
|
||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||
|
||||
- ``org/add_solution`` (seminar_vloz_reseni) :class:`~odevzdavatko.views.PosliReseniView`
|
||||
- ``resitel/nahraj_reseni`` (seminar_nahraj_reseni) :class:`~odevzdavatko.views.NahrajReseniView`
|
||||
- ``resitel/odevzdana_reseni/`` (seminar_resitel_odevzdana_reseni) :class:`~odevzdavatko.views.PrehledOdevzdanychReseni`
|
||||
- ``org/reseni/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
||||
- ``org/reseni/rocnik/<int:rocnik>/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
||||
- ``org/reseni/<int:problem>/<int:resitel>/`` (odevzdavatko_reseni_resitele_k_problemu) :class:`~odevzdavatko.views.ReseniProblemuView`
|
||||
- ``org/reseni/<int:pk>/`` (odevzdavatko_detail_reseni) :func:`~seminar.utils.viewMethodSwitch` + :class:`~odevzdavatko.views.DetailReseniView` + :func:`~odevzdavatko.views.hodnoceniReseniView`
|
||||
- ``org/reseni/all`` :class:`~odevzdavatko.views.SeznamReseniView`
|
||||
- ``org/reseni/akt`` :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
||||
- ``resitel/reseni/<int:pk>`` (odevzdavatko_resitel_reseni) :class:`~odevzdavatko.views.ResitelReseniView`
|
||||
"""
|
||||
from django.urls import path
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from . import views
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
"""
|
||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||
|
||||
- ``prednasky/`` :func:`~prednasky.views.newPrednaska`
|
||||
- ``prednasky/hotovo`` :func:`~prednasky.views.Prednaska_hotovo`
|
||||
- ``prednasky/metaseznam_prednasek`` (metaseznam-list) :class:`~prednasky.views.MetaSeznamListView`
|
||||
- ``prednasky/seznam_prednasek/<int:seznam>/export`` (seznam-export) :func:`~prednasky.views.SeznamExportView`
|
||||
- ``prednasky/seznam_prednasek/<int:seznam>/`` (seznam-list) :class:`~prednasky.views.SeznamListView`
|
||||
"""
|
||||
from django.urls import path
|
||||
from seminar.utils import org_required, resitel_required
|
||||
from . import views
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
"""
|
||||
Zde bývalo vše. Teď tu zbývají všechny modely a části webu jako archiv,
|
||||
přehled orgů, aktuální (k aktuálnímu číslu) věci, titulka a jak řešit.
|
||||
|
||||
Také je tu generování testovacích (lokálních) dat.
|
||||
"""
|
|
@ -1,3 +1,35 @@
|
|||
"""
|
||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||
|
||||
- Organizátoři
|
||||
- ``o-nas/organizatori/`` (organizatori) :class:`~seminar.views.views_all.CojemamOrganizatoriView`
|
||||
- ``o-nas/organizatori/organizovali/`` (stari_organizatori) :class:`~seminar.views.views_all.CojemamOrganizatoriStariView`
|
||||
- Archiv
|
||||
- ``archiv/rocniky/`` (seminar_archiv_rocniky) :class:`~seminar.views.views_all.ArchivView`
|
||||
- ``archiv/temata/`` (seminar_archiv_temata) :class:`~seminar.views.views_all.ArchivTemataView`
|
||||
- ``rocnik/<int:rocnik>/`` (seminar_rocnik) :class:`~seminar.views.views_all.RocnikView`
|
||||
- ``cislo/<int:rocnik>.<str:cislo>/`` (seminar_cislo) :class:`~seminar.views.views_all.CisloView`
|
||||
- ``problem/<int:pk>/`` (seminar_problem) :func:`~seminar.views.views_all.problemView`
|
||||
- Zadání
|
||||
- ``aktualni/zadani/`` (seminar_aktualni_zadani) :func:`~seminar.views.views_all.AktualniZadaniView`
|
||||
- ``aktualni/vysledkova-listina/`` (seminar_aktualni_vysledky) :func:`~seminar.views.views_all.ZadaniAktualniVysledkovkaView`
|
||||
- ``aktualni/rocnik/`` (seminar_aktualni_rocnik) :class:`~seminar.views.views_all.AktualniRocnikRedirectView`
|
||||
- Články
|
||||
- ``archiv/clanky/`` (clanky_resitel) :class:`~seminar.views.views_all.ClankyResitelView`
|
||||
- Orgovské stránky
|
||||
- ``rocnik/<int:rocnik>/vysledkovka.tex`` (seminar_rocnik_vysledkovka) :class:`~seminar.views.views_all.RocnikVysledkovkaView`
|
||||
- ``rocnik/<int:rocnik>/resitele.csv`` (seminar_rocnik_resitele_csv) :func:`~seminar.views.views_all.resiteleRocnikuCsvExportView`
|
||||
- ``cislo/<int:rocnik>.<str:cislo>/vysledkovka.tex`` (seminar_cislo_vysledkovka) :class:`~seminar.views.views_all.CisloVysledkovkaView`
|
||||
- ``cislo/<int:rocnik>.<str:cislo>/obalky.pdf`` (seminar_cislo_obalky) :func:`~seminar.views.views_all.cisloObalkyView`
|
||||
- ``cislo/<int:rocnik>.<str:cislo>/tituly.tex`` (seminar_cislo_titul) :func:`~seminar.views.views_all.TitulyView`
|
||||
- ``stav`` (stav_databaze) :func:`~seminar.views.views_all.StavDatabazeView`
|
||||
- ``cislo/<int:rocnik>.<str:cislo>/obalkovani`` (seminar_cislo_resitel_obalkovani) :class:`~seminar.views.views_all.ObalkovaniView`
|
||||
- ``cislo/<int:trocnik>.<str:tcislo>/odmeny/<int:frocnik>.<str:fcislo>/`` (seminar_archiv_odmeny) :class:`~seminar.views.views_all.OdmenyView`
|
||||
- Další
|
||||
- `` `` (titulni_strana) :class:`~seminar.views.views_all.TitulniStranaView`
|
||||
- ``jak-resit/`` (jak_resit) :class:`~seminar.views.views_all.JakResitView`
|
||||
- ``stare-novinky/`` (stare_novinky) :class:`~seminar.views.views_all.StareNovinkyView`
|
||||
"""
|
||||
from django.urls import path, include, re_path
|
||||
from . import views
|
||||
from .utils import org_required
|
||||
|
@ -24,7 +56,6 @@ urlpatterns = [
|
|||
#path('aktualni/temata/', views.ZadaniTemataView, name='seminar_temata'),
|
||||
path('aktualni/vysledkova-listina/', views.ZadaniAktualniVysledkovkaView, name='seminar_aktualni_vysledky'),
|
||||
path('aktualni/rocnik/', views.AktualniRocnikRedirectView.as_view(), name='seminar_aktualni_rocnik'),
|
||||
path('stare-novinky/', views.StareNovinkyView.as_view(), name='stare_novinky'),
|
||||
|
||||
# Clanky
|
||||
path('archiv/clanky/', views.ClankyResitelView.as_view(), name='clanky_resitel'),
|
||||
|
@ -73,4 +104,5 @@ urlpatterns = [
|
|||
|
||||
path('', views.TitulniStranaView.as_view(), name='titulni_strana'),
|
||||
path('jak-resit/', views.JakResitView.as_view(), name='jak_resit'),
|
||||
path('stare-novinky/', views.StareNovinkyView.as_view(), name='stare_novinky'),
|
||||
]
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
"""
|
||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
||||
"""
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
"""
|
||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
||||
"""
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
"""
|
||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||
|
||||
- Zatím tu nic moc není…
|
||||
"""
|
||||
from django.urls import path, re_path
|
||||
from . import views
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
"""
|
||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
||||
"""
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
"""
|
||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||
|
||||
- ``prihlasit/`` (login) :class:`~various.autentizace.views.LoginView`
|
||||
- ``login/`` :class:`django.views.generic.base.RedirectView` předchozího
|
||||
- ``odhlasit/`` (logout) :class:`~various.autentizace.views.LogoutView`
|
||||
- ``logout/`` :class:`django.views.generic.base.RedirectView` předchozího
|
||||
- ``reset-hesla/`` (reset_password) :class:`~various.autentizace.views.PasswordResetView`
|
||||
- ``zmena-hesla/`` (change_password) :class:`~various.autentizace.views.PasswordChangeView`
|
||||
- ``zmena-hesla/2/`` (reset_password_done) :class:`~various.autentizace.views.PasswordResetDoneView`
|
||||
- ``reset-hesla/potvrzeni/<uidb64>/<token>/`` (reset_password_confirm) :class:`~various.autentizace.views.PasswordResetConfirmView`
|
||||
- ``reset-hesla/hotovo/`` (reset_password_complete) :class:`~various.autentizace.views.PasswordResetCompleteView`
|
||||
"""
|
||||
from django.urls import path
|
||||
from . import views
|
||||
from django.views.generic.base import RedirectView
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
"""
|
||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
||||
"""
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue