You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

325 lines
9.7 KiB

from django.contrib import admin
from django.contrib.auth.models import Group
from django.db import models
from django.forms import widgets, ModelForm
from django.core.exceptions import ValidationError
from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin, PolymorphicChildModelFilter
from reversion.admin import VersionAdmin
from django_reverse_admin import ReverseModelAdmin
from solo.admin import SingletonModelAdmin
from django.utils.safestring import mark_safe
from seminar.views.vysledkovka import hlavni_problem
# TODO Přesunout do utils
# Todo: reversion
import seminar.models as m
import seminar.treelib as tl
admin.site.register(m.Skola)
admin.site.register(m.Prijemce)
admin.site.register(m.Rocnik)
class CisloForm(ModelForm):
class Meta:
model = m.Cislo
fields = '__all__'
def clean(self):
if self.cleaned_data.get('verejne_db') == False:
return self.cleaned_data
cn = m.CisloNode.objects.get(cislo=self.instance)
errors = []
for ch in tl.all_children(cn):
if isinstance(ch, m.TemaVCisleNode):
if ch.tema.stav not in \
(m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY):
errors.append(ValidationError('Téma %(tema)s není zadané ani vyřešené', params={'tema':ch.tema}))
if isinstance(ch, m.UlohaZadaniNode) or isinstance(ch, m.UlohaVzorakNode):
if ch.uloha.stav not in \
(m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY):
errors.append(ValidationError('Úloha %(uloha)s není zadaná ani vyřešená', params={'uloha':ch.uloha}))
if isinstance(ch, m.ReseniNode):
for problem in ch.reseni.problem_set:
if problem not in \
(m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY):
errors.append(ValidationError('Problém %s není zadaný ani vyřešený', code=problem))
if errors:
errors.append(ValidationError(mark_safe('<b>Pokud chceš učinit všechny problémy, co nejsou zadané ani vyřešené, zadanými a číslo zveřejnit, můžeš to udělat pomocí akce v <a href="/admin/seminar/cislo">seznamu čísel</a></b>')))
raise ValidationError(errors)
return self.cleaned_data
@admin.register(m.Cislo)
class CisloAdmin(admin.ModelAdmin):
form = CisloForm
actions = ['force_publish']
def force_publish(self,request,queryset):
for cislo in queryset:
# cn = m.CisloNode.objects.get(cislo=cislo)
# for ch in tl.all_children(cn):
# if isinstance(ch, m.TemaVCisleNode):
# if ch.tema.stav not in (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY):
# ch.tema.stav = m.Problem.STAV_ZADANY
# ch.tema.save()
#
# if isinstance(ch, m.UlohaZadaniNode) or isinstance(ch, m.UlohaVzorakNode):
# if ch.uloha.stav not in (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY):
# ch.uloha.stav = m.Problem.STAV_ZADANY
# ch.uloha.save()
# if isinstance(ch, m.ReseniNode):
# for problem in ch.reseni.problem_set:
# if problem not in (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY):
# problem.stav = m.Problem.STAV_ZADANY
# problem.save()
for ch in m.Uloha.objects.filter(cislo_zadani=cislo):
if ch.stav not in (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY):
ch.stav = m.Problem.STAV_ZADANY
ch.save()
hp = hlavni_problem(ch)
if hp.stav not in (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY):
hp.stav = m.Problem.STAV_ZADANY
hp.save()
# TODO Řešení, vzoráky?
# TODO Konfera/Článek?
cislo.verejne_db = True
cislo.save()
force_publish.short_description = 'Zveřejnit vybraná čísla a všechny návrhy úloh v nich učinit zadanými'
@admin.register(m.Osoba)
class OsobaAdmin(admin.ModelAdmin):
actions = ['synchronizuj_maily', 'udelej_orgem']
def synchronizuj_maily(self, request, queryset):
for o in queryset:
if o.user is not None:
u = o.user
u.email = o.email
u.save()
self.message_user(request, "E-maily synchronizovány.")
synchronizuj_maily.short_description = "Synchronizuj vybraným osobám e-maily do uživatelů"
def udelej_orgem(self,request,queryset):
org_group = Group.objects.get(name='org')
print(queryset)
for o in queryset:
user = o.user
print(user)
user.groups.add(org_group)
user.is_staff = True
user.save()
org = m.Organizator.objects.create(osoba=o)
org.save()
udelej_orgem.short_description = "Udělej vybraných osob organizátory"
@admin.register(m.Organizator)
class OrganizatorAdmin(admin.ModelAdmin):
search_fields = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__prezdivka']
@admin.register(m.Resitel)
class ResitelAdmin(admin.ModelAdmin):
search_fields = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__prezdivka']
ordering = ('osoba__jmeno','osoba__prijmeni')
@admin.register(m.Problem)
class ProblemAdmin(PolymorphicParentModelAdmin):
base_model = m.Problem
child_models = [
m.Tema,
m.Clanek,
m.Uloha,
m.Konfera,
]
# Pokud chceme orezavat na aktualni rocnik, musime do modelu pridat odkaz na rocnik. Zatim bere vse.
search_fields = ['nazev']
# V ProblemAdmin to nejde, protoze se to nepropise do deti
class ProblemAdminMixin(object):
show_in_index = True
autocomplete_fields = ['nadproblem','autor','garant']
filter_horizontal = ['opravovatele']
@admin.register(m.Tema)
class TemaAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin):
base_model = m.Tema
@admin.register(m.Clanek)
class ClanekAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin):
base_model = m.Clanek
@admin.register(m.Uloha)
class UlohaAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin):
base_model = m.Uloha
@admin.register(m.Konfera)
class KonferaAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin):
base_model = m.Konfera
class TextAdminInline(admin.TabularInline):
model = m.Text
formfield_overrides = {
models.TextField: {'widget': widgets.TextInput}
}
exclude = ['text_zkraceny_set','text_zkraceny']
admin.site.register(m.Text)
class ResitelInline(admin.TabularInline):
model = m.Resitel
extra = 1
class SoustredeniUcastniciInline(admin.TabularInline):
model = m.Soustredeni_Ucastnici
extra = 1
fields = ['resitel','poznamka']
autocomplete_fields = ['resitel']
ordering = ['resitel__osoba__jmeno', 'resitel__osoba__prijmeni']
formfield_overrides = {
models.TextField: {'widget': widgets.TextInput}
}
def get_queryset(self,request):
qs = super().get_queryset(request)
return qs.select_related('resitel','soustredeni')
class SoustredeniOrganizatoriInline(admin.TabularInline):
model = m.Soustredeni.organizatori.through
extra = 1
fields = ['organizator','poznamka']
autocomplete_fields = ['organizator']
ordering = ['organizator__osoba__jmeno','organizator__prijmeni']
formfield_overrides = {
models.TextField: {'widget': widgets.TextInput}
}
def get_queryset(self,request):
qs = super().get_queryset(request)
return qs.select_related('organizator', 'soustredeni')
@admin.register(m.Soustredeni)
class SoustredeniAdmin(admin.ModelAdmin):
model = m.Soustredeni
inline_type = 'tabular'
inlines = [SoustredeniUcastniciInline, SoustredeniOrganizatoriInline]
class PrilohaReseniInline(admin.TabularInline):
model = m.PrilohaReseni
extra = 1
admin.site.register(m.PrilohaReseni)
class Reseni_ResiteleInline(admin.TabularInline):
model = m.Reseni_Resitele
@admin.register(m.Reseni)
class ReseniAdmin(ReverseModelAdmin):
base_model = m.Reseni
inline_type = 'tabular'
inline_reverse = ['text_cely','resitele']
exclude = ['text_zkraceny', 'text_zkraceny_set']
inlines = [PrilohaReseniInline]
# FAIL in template
# inlines = [PrilohaReseniInline,Reseni_ResiteleInline]
admin.site.register(m.Hodnoceni)
admin.site.register(m.Pohadka)
admin.site.register(m.Obrazek)
# Polymorfismus pro stromy
# TODO: Inlines podle https://django-polymorphic.readthedocs.io/en/stable/admin.html
@admin.register(m.TreeNode)
class TreeNodeAdmin(PolymorphicParentModelAdmin):
base_model = m.TreeNode
child_models = [
m.RocnikNode,
m.CisloNode,
m.MezicisloNode,
m.TemaVCisleNode,
m.UlohaZadaniNode,
m.PohadkaNode,
m.UlohaVzorakNode,
m.TextNode,
m.CastNode,
m.OrgTextNode,
]
actions = ['aktualizuj_nazvy']
# XXX: nejspíš je to totální DB HOG, nechcete to použít moc často.
def aktualizuj_nazvy(self, request, queryset):
newqs = queryset.get_real_instances()
for tn in newqs:
tn.aktualizuj_nazev()
tn.save()
self.message_user(request, "Názvy aktualizovány.")
aktualizuj_nazvy.short_description = "Aktualizuj vybraným TreeNodům názvy"
@admin.register(m.RocnikNode)
class RocnikNodeAdmin(PolymorphicChildModelAdmin):
base_model = m.RocnikNode
show_in_index = True
@admin.register(m.CisloNode)
class CisloNodeAdmin(PolymorphicChildModelAdmin):
base_model = m.CisloNode
show_in_index = True
@admin.register(m.MezicisloNode)
class MezicisloNodeAdmin(PolymorphicChildModelAdmin):
base_model = m.MezicisloNode
show_in_index = True
@admin.register(m.TemaVCisleNode)
class TemaVCisleNodeAdmin(PolymorphicChildModelAdmin):
base_model = m.TemaVCisleNode
show_in_index = True
@admin.register(m.UlohaZadaniNode)
class UlohaZadaniNodeAdmin(PolymorphicChildModelAdmin):
base_model = m.UlohaZadaniNode
show_in_index = True
@admin.register(m.PohadkaNode)
class PohadkaNodeAdmin(PolymorphicChildModelAdmin):
base_model = m.PohadkaNode
show_in_index = True
@admin.register(m.UlohaVzorakNode)
class UlohaVzorakNodeAdmin(PolymorphicChildModelAdmin):
base_model = m.UlohaVzorakNode
show_in_index = True
@admin.register(m.TextNode)
class TextNodeAdmin(PolymorphicChildModelAdmin):
base_model = m.TextNode
show_in_index = True
@admin.register(m.CastNode)
class TextNodeAdmin(PolymorphicChildModelAdmin):
base_model = m.CastNode
show_in_index = True
fields = ('nadpis',)
@admin.register(m.OrgTextNode)
class TextNodeAdmin(PolymorphicChildModelAdmin):
base_model = m.OrgTextNode
show_in_index = True
admin.site.register(m.Nastaveni, SingletonModelAdmin)
admin.site.register(m.Novinky)