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 # 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('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 seznamu čísel'))) 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() 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)