Browse Source

Přesun stavu databáze do various (dokončeno rozebírání seminar.utils)

Důvodem je, že mi přijde, že stav databáze je dosti složitá a neviditelná věc, na to, aby byla přímo v semináři
v3
Jonas Havelka 1 year ago
parent
commit
9412a52567
  1. 3
      seminar/urls.py
  2. 96
      seminar/utils.py
  3. 21
      seminar/views/views_all.py
  4. 99
      various/utils.py
  5. 24
      various/views.py

3
seminar/urls.py

@ -1,6 +1,7 @@
from django.urls import path, include, re_path from django.urls import path, include, re_path
from . import views from . import views
from personalni.utils import org_required from personalni.utils import org_required
import various.views
urlpatterns = [ urlpatterns = [
# path('aktualni/temata/', views.TemataRozcestnikView), # path('aktualni/temata/', views.TemataRozcestnikView),
@ -67,7 +68,7 @@ urlpatterns = [
), ),
path( path(
'stav', 'stav',
org_required(views.StavDatabazeView), org_required(various.views.StavDatabazeView),
name='stav_databaze' name='stav_databaze'
), ),
path( path(

96
seminar/utils.py

@ -1,96 +0,0 @@
import datetime
from django.contrib.contenttypes.models import ContentType
from personalni.models import Resitel
from tvorba.models import Clanek
from treenode.models import CisloNode
import treenode.treelib as t
def histogram(seznam):
d = {}
for i in seznam:
if i not in d:
d[i] = 0
d[i] += 1
return d
def seznam_problemu():
"""Funkce pro hledání nekonzistencí v databázi a dalších nežádoucích stavů webu/databáze.
Nijak nesouvisí s Problémy zadanými řešitelům."""
# FIXME: přejmenovat funkci?
# FIXME: Tak, jak je napsaná, asi spíš patří někam k views a ne do utils (?)
problemy = []
# Pomocna fce k formatovani problemovych hlasek
def prb(cls, msg, objs=None):
s = '<b>%s:</b> %s' % (cls.__name__, msg)
if objs:
s += ' ['
for o in objs:
try:
url = o.admin_url()
except:
url = None
if url:
s += '<a href="%s">%s</a>, ' % (url, o.pk,)
else:
s += '%s, ' % (o.pk,)
s = s[:-2] + ']'
problemy.append(s)
# Duplicita jmen
jmena = {}
for r in Resitel.objects.all():
j = r.osoba.plne_jmeno()
if j not in jmena:
jmena[j] = []
jmena[j].append(r)
for j in jmena:
if len(jmena[j]) > 1:
prb(Resitel, 'Duplicitní jméno "%s"' % (j,), jmena[j])
# Data maturity a narození
for r in Resitel.objects.all():
if not r.rok_maturity:
prb(Resitel, 'Neznámý rok maturity', [r])
if r.rok_maturity and (r.rok_maturity < 1990 or r.rok_maturity > datetime.date.today().year + 10):
prb(Resitel, 'Podezřelé datum maturity', [r])
if r.osoba.datum_narozeni and (
r.osoba.datum_narozeni.year < 1970 or r.osoba.datum_narozeni.year > datetime.date.today().year - 12):
prb(Resitel, 'Podezřelé datum narození', [r])
# if not r.email:
# prb(Resitel, u'Neznámý email', [r])
## Kontroly konzistence databáze a TreeNodů
# Články
for clanek in Clanek.objects.all():
# získáme řešení svázané se článkem a z něj node ve stromě
reseni = clanek.reseni_set
if (reseni.count() != 1):
raise ValueError("Článek k sobě má nejedno řešení!")
r = reseni.first()
clanek_node = r.text_cely # vazba na ReseniNode z Reseni
# content type je věc pomáhající rozeznávat různé typy objektů v django-polymorphic
# protože isinstance vrátí vždy jen TreeNode
# https://django-polymorphic.readthedocs.io/en/stable/migrating.html
cislonode_ct = ContentType.objects.get_for_model(CisloNode)
node = clanek_node
while node is not None:
node_ct = node.polymorphic_ctype
if node_ct == cislonode_ct: # dostali jsme se k CisloNode
# zkontrolujeme, že stromové číslo odpovídá atributu
# .cislonode je opačná vazba k treenode_ptr, abychom z TreeNode dostali
# CisloNode
if clanek.cislo != node.cislonode.cislo:
prb(Clanek, "Číslo otištění uložené u článku nesedí s "
"číslem otištění podle struktury treenodů.", [clanek])
break
node = t.get_parent(node)
return problemy

21
seminar/views/views_all.py

@ -14,7 +14,6 @@ from seminar.models.nastaveni import Nastaveni
from personalni.models import Resitel, Organizator from personalni.models import Resitel, Organizator
from seminar.models.novinky import Novinky from seminar.models.novinky import Novinky
#from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
from seminar import utils
from treenode import treelib from treenode import treelib
import treenode.templatetags as tnltt import treenode.templatetags as tnltt
import treenode.serializers as vr import treenode.serializers as vr
@ -658,26 +657,6 @@ class ClankyResitelView(generic.ListView):
# queryset = Problem.objects.filter(stav=Problem.STAV_ZADANY).select_related('cislo_zadani__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod') # queryset = Problem.objects.filter(stav=Problem.STAV_ZADANY).select_related('cislo_zadani__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod')
### Status
def StavDatabazeView(request):
# nastaveni = Nastaveni.objects.get()
problemy = utils.seznam_problemu()
muzi = Resitel.objects.filter(osoba__pohlavi_muz=True)
zeny = Resitel.objects.filter(osoba__pohlavi_muz=False)
return render(request, 'seminar/stav_databaze.html',
{
# 'nastaveni': nastaveni,
'problemy': problemy,
'resitele': Resitel.objects.all(),
'muzi': muzi,
'zeny': zeny,
'jmena_muzu': utils.histogram([r.osoba.jmeno for r in muzi]),
'jmena_zen': utils.histogram([r.osoba.jmeno for r in zeny]),
})
# Interní, nemá se nikdy objevit v urls (jinak to účastníci vytrolí) # Interní, nemá se nikdy objevit v urls (jinak to účastníci vytrolí)
def formularOKView(request, text='', dalsi_odkazy: Sequence[tuple[str, str]] = ()): def formularOKView(request, text='', dalsi_odkazy: Sequence[tuple[str, str]] = ()):
template_name = 'seminar/formular_ok.html' template_name = 'seminar/formular_ok.html'

99
various/utils.py

@ -1,4 +1,8 @@
import datetime
from django import views as DjangoViews from django import views as DjangoViews
from django.contrib.contenttypes.models import ContentType
bez_diakritiky = ({} bez_diakritiky = ({}
# FIXME: funguje jen pro český a slovenský text, jinak jsou špatně # FIXME: funguje jen pro český a slovenský text, jinak jsou špatně
@ -81,3 +85,98 @@ def viewMethodSwitch(get, post):
return thePostView(request, *args, **kwargs) return thePostView(request, *args, **kwargs)
return NewView.as_view() return NewView.as_view()
def histogram(seznam):
d = {}
for i in seznam:
if i not in d:
d[i] = 0
d[i] += 1
return d
def seznam_problemu():
"""Funkce pro hledání nekonzistencí v databázi a dalších nežádoucích stavů webu/databáze.
Nijak nesouvisí s Problémy zadanými řešitelům."""
# FIXME: přejmenovat funkci?
# FIXME: Tak, jak je napsaná, asi spíš patří někam k views a ne do utils (?)
# Importy tady, aby various.utils zůstalo čisté od ostatních částí mamwebu
# obrana proti cyklickým importům...
from personalni.models import Resitel
from tvorba.models import Clanek
from treenode.models import CisloNode
import treenode.treelib as t
problemy = []
# Pomocna fce k formatovani problemovych hlasek
def prb(cls, msg, objs=None):
s = '<b>%s:</b> %s' % (cls.__name__, msg)
if objs:
s += ' ['
for o in objs:
try:
url = o.admin_url()
except:
url = None
if url:
s += '<a href="%s">%s</a>, ' % (url, o.pk,)
else:
s += '%s, ' % (o.pk,)
s = s[:-2] + ']'
problemy.append(s)
# Duplicita jmen
jmena = {}
for r in Resitel.objects.all():
j = r.osoba.plne_jmeno()
if j not in jmena:
jmena[j] = []
jmena[j].append(r)
for j in jmena:
if len(jmena[j]) > 1:
prb(Resitel, 'Duplicitní jméno "%s"' % (j,), jmena[j])
# Data maturity a narození
for r in Resitel.objects.all():
if not r.rok_maturity:
prb(Resitel, 'Neznámý rok maturity', [r])
if r.rok_maturity and (r.rok_maturity < 1990 or r.rok_maturity > datetime.date.today().year + 10):
prb(Resitel, 'Podezřelé datum maturity', [r])
if r.osoba.datum_narozeni and (
r.osoba.datum_narozeni.year < 1970 or r.osoba.datum_narozeni.year > datetime.date.today().year - 12):
prb(Resitel, 'Podezřelé datum narození', [r])
# if not r.email:
# prb(Resitel, u'Neznámý email', [r])
## Kontroly konzistence databáze a TreeNodů
# Články
for clanek in Clanek.objects.all():
# získáme řešení svázané se článkem a z něj node ve stromě
reseni = clanek.reseni_set
if (reseni.count() != 1):
raise ValueError("Článek k sobě má nejedno řešení!")
r = reseni.first()
clanek_node = r.text_cely # vazba na ReseniNode z Reseni
# content type je věc pomáhající rozeznávat různé typy objektů v django-polymorphic
# protože isinstance vrátí vždy jen TreeNode
# https://django-polymorphic.readthedocs.io/en/stable/migrating.html
cislonode_ct = ContentType.objects.get_for_model(CisloNode)
node = clanek_node
while node is not None:
node_ct = node.polymorphic_ctype
if node_ct == cislonode_ct: # dostali jsme se k CisloNode
# zkontrolujeme, že stromové číslo odpovídá atributu
# .cislonode je opačná vazba k treenode_ptr, abychom z TreeNode dostali
# CisloNode
if clanek.cislo != node.cislonode.cislo:
prb(Clanek, "Číslo otištění uložené u článku nesedí s "
"číslem otištění podle struktury treenodů.", [clanek])
break
node = t.get_parent(node)
return problemy

24
various/views.py

@ -1,3 +1,25 @@
from django.shortcuts import render from django.shortcuts import render
# Create your views here. from various import utils
from personalni.models import Resitel
def StavDatabazeView(request):
# nastaveni = Nastaveni.objects.get()
problemy = utils.seznam_problemu()
muzi = Resitel.objects.filter(osoba__pohlavi_muz=True)
zeny = Resitel.objects.filter(osoba__pohlavi_muz=False)
return render(
request,
'seminar/stav_databaze.html',
{
# 'nastaveni': nastaveni,
'problemy': problemy,
'resitele': Resitel.objects.all(),
'muzi': muzi,
'zeny': zeny,
'jmena_muzu': utils.histogram([r.osoba.jmeno for r in muzi]),
'jmena_zen': utils.histogram([r.osoba.jmeno for r in zeny]),
}
)

Loading…
Cancel
Save