# -*- coding: utf-8 -*- from django.contrib import admin from django import forms from django.forms import widgets from reversion.admin import VersionAdmin from solo.admin import SingletonModelAdmin from ckeditor.widgets import CKEditorWidget from django.db.models import Count from django.db import models from django.contrib.auth.models import User from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Novinky, Organizator import autocomplete_light class UserModelChoiceField(forms.ModelChoiceField): u"""Vlastní ModelChoiceField pro uživatele. Zobrazí kromě loginu i jméno. """ def label_from_instance(self, obj): return u"{} ({})".format(obj.get_full_name(), obj.username) def get_form_predvypln_autora(self, request, obj=None, *args, **kwargs): u"""get_form fce pro Adminy. Předvyplňí přihlášeného uživatele jako autora. """ form = super(self.__class__, self).get_form(request, *args, **kwargs) form.base_fields['autor'].initial = request.user.id return form def make_set_action(atribut, hodnota, nazev): u""" Pomocnik pro rychle vytvareni hromadnych admin akci ktere jen nastavuji atribut (dany jako string) na danou hodnotu. nazev je krátký popis akce pro admin rozhraní.""" def action_f(modeladmin, request, queryset): for obj in queryset: assert atribut in obj.__dict__ obj.__setattr__(atribut, hodnota) obj.save() action_f.short_description = nazev # Trik: je potřeba, aby se funkce různě (ale libovolně) jmenovaly, # jinak je Django v seznamu akcí splácne do jedné action_f.__name__ = 'action_f_%d_%d_%d' % (id(atribut), id(hodnota), id(nazev), ) return action_f ### Globální nastavení admin.site.register(Nastaveni, SingletonModelAdmin) ### UTILS (pro verbose_name a help_text) def field_labels(model, fieldname): f = [i for i in model._meta.fields if i.name == fieldname][0] return {'label': f.verbose_name.capitalize(), 'help_text': f.help_text, } def create_modeladmin(modeladmin, model, name = None, verbose_name = None, verbose_name_plural = None): class Meta: proxy = True app_label = model._meta.app_label Meta.verbose_name = verbose_name Meta.verbose_name_plural = verbose_name_plural attrs = {'__module__': '', 'Meta': Meta} newmodel = type(name, (model,), attrs) admin.site.register(newmodel, modeladmin) return modeladmin ### INLINES class ResitelInline(admin.TabularInline): model = Resitel fields = ['jmeno', 'prijmeni', 'skola', 'mesto', 'rok_maturity', ] readonly_fields = ['jmeno', 'prijmeni', 'skola', 'mesto', 'rok_maturity', ] extra = 0 def has_add_permission(self, req): return False class CisloInline(admin.TabularInline): model = Cislo fields = ['cislo', 'datum_vydani', 'datum_deadline', 'verejne_db', 'poznamka'] readonly_fields = ['cislo'] extra = 0 formfield_overrides = { models.TextField: {'widget': forms.TextInput}, } def has_add_permission(self, req): return False class PrilohaReseniInline(admin.StackedInline): model = PrilohaReseni fields = ['timestamp', 'soubor', 'poznamka'] readonly_fields = ['timestamp'] formfield_overrides = { models.TextField: {'widget': forms.TextInput}, } extra = 0 class ReseniKProblemuInline(admin.TabularInline): form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['resitel'], fields=['resitel']) model = Reseni fields = ['resitel', 'forma', 'body', 'cislo_body', 'timestamp', 'poznamka'] readonly_fields = ['timestamp'] extra = 0 formfield_overrides = { models.TextField: {'widget': forms.TextInput}, } def get_queryset(self, request): qs = super(ReseniKProblemuInline, self).get_queryset(request) return qs.select_related('problem', 'cislo_body', 'resitel') # Potenciální DB HOG (cislo_body se dotazovalo na cisla pri kazdem zobrazeni jejich selectu ...) def formfield_for_dbfield(self, db_field, **kwargs): formfield = super(ReseniKProblemuInline, self).formfield_for_dbfield(db_field, **kwargs) if db_field.name == 'cislo_body': # dirty trick so queryset is evaluated and cached in .choices formfield.choices = formfield.choices return formfield class ReseniKResiteliInline(admin.TabularInline): model = Reseni fields = ['problem', 'forma', 'body', 'cislo_body', 'timestamp', 'poznamka'] readonly_fields = ['timestamp', 'problem'] extra = 0 formfield_overrides = { models.TextField: {'widget': forms.TextInput}, } def has_add_permission(self, req): return False def get_queryset(self, request): qs = super(ReseniKResiteliInline, self).get_queryset(request) return qs.select_related('problem', 'cislo_body', 'resitel') # Potenciální DB HOG (cislo_body se dotazovalo na cisla pri kazdem zobrazeni jejich selectu ...) def formfield_for_dbfield(self, db_field, **kwargs): formfield = super(ReseniKResiteliInline, self).formfield_for_dbfield(db_field, **kwargs) if db_field.name == 'cislo_body': # dirty trick so queryset is evaluated and cached in .choices formfield.choices = formfield.choices return formfield class Soustredeni_UcastniciInline(admin.TabularInline): form = autocomplete_light.modelform_factory(Soustredeni_Ucastnici, autocomplete_fields=['resitel'], fields=['resitel']) model = Soustredeni_Ucastnici fields = ['resitel', 'poznamka', ] extra = 0 formfield_overrides = { models.TextField: {'widget': forms.TextInput}, } def get_queryset(self, request): qs = super(Soustredeni_UcastniciInline, self).get_queryset(request) return qs.select_related('resitel', 'soustredeni') ### Resitel class ResitelAdmin(VersionAdmin): form = autocomplete_light.modelform_factory(Resitel, autocomplete_fields=['skola'], fields=['skola']) fieldsets = [ (None, {'fields': ['jmeno', 'prijmeni', 'user']}), (u'Škola', {'fields': ['skola', 'rok_maturity']}), (u'Seminář', {'fields': ['datum_souhlasu_udaje', 'datum_souhlasu_zasilani', 'datum_prihlaseni', 'zasilat']}), (u'Osobní údaje', {'fields': ['pohlavi_muz', 'datum_narozeni', 'email', 'telefon']}), (u'Adresa', {'fields': ['ulice', 'mesto', 'psc', 'stat']}), ] list_display = ['jmeno', 'prijmeni', 'user', 'pohlavi_muz', 'skola', 'rok_maturity', 'pocet_reseni'] list_filter = ['pohlavi_muz', 'rok_maturity', 'zasilat'] search_fields = ['jmeno', 'prijmeni', 'ulice', 'mesto', 'email'] inlines = [ReseniKResiteliInline] def get_queryset(self, request): qs = super(ResitelAdmin, self).get_queryset(request) return qs.select_related('skola', 'user').annotate(pocet_reseni=Count('reseni')) def pocet_reseni(self, obj): return obj.pocet_reseni admin.site.register(Resitel, ResitelAdmin) ### Skola class SkolaAdmin(VersionAdmin): fieldsets = [ (None, {'fields': ['nazev', 'kratky_nazev', 'je_zs', 'je_ss']}), (u'Interní ID', {'fields': ['aesop_id', 'izo'], 'classes': ['collapse']}), (u'Adresa', {'fields': ['ulice', 'mesto', 'psc', 'stat']}), (None, {'fields': ['poznamka']}), ] list_display = ['nazev', 'aesop_id', 'mesto', 'ulice', 'stat', 'je_zs', 'je_ss'] list_filter = ['stat', 'je_zs', 'je_ss'] search_fields = ['nazev', 'mesto', 'ulice'] inlines = [ResitelInline] admin.site.register(Skola, SkolaAdmin) ### Cislo class CisloAdmin(VersionAdmin): fieldsets = [ (None, {'fields': ['cislo', 'rocnik', 'verejne_db', 'verejna_vysledkovka', 'poznamka', 'pdf']}), (u'Data', {'fields': ['datum_vydani', 'datum_deadline']}), ] list_display = ['kod', 'rocnik', 'cislo', 'datum_vydani', 'datum_deadline', 'verejne', 'verejna_vysledkovka'] list_filter = ['rocnik'] view_on_site = Cislo.verejne_url actions = [ make_set_action('verejne_db', True, u'Zveřejnit číslo'), make_set_action('verejne_db', False, u'Skrýt (zneveřejnit) číslo'), make_set_action('verejna_vysledkovka', True, u'Zveřejnit výsledkovku'), make_set_action('verejna_vysledkovka', False, u'Skrýt (zneveřejnit) výsledkovku'), ] def get_queryset(self, request): qs = super(CisloAdmin, self).get_queryset(request) return qs.select_related('rocnik') admin.site.register(Cislo, CisloAdmin) ### Rocnik class RocnikAdmin(VersionAdmin): fieldsets = [ (None, {'fields': ['rocnik', 'prvni_rok', 'exportovat']}), ] list_display = ['rocnik', 'prvni_rok', 'exportovat', 'verejne'] inlines = [CisloInline] view_on_site = Rocnik.verejne_url actions = [ make_set_action('exportovat', True, u'Nastavit pro AESOP export'), make_set_action('exportovat', False, u'Skrýt pro AESOP export'), ] admin.site.register(Rocnik, RocnikAdmin) ### PrilohaReseni # NOTE: Nemá pravděpodobně smysl používat # class PrilohaReseniAdmin(reversion.VersionAdmin): # readonly_fields = ['timestamp', 'reseni'] # fieldsets = [ # (None, {'fields': ['reseni', 'soubor', 'timestamp']}), # (u'Poznámky', {'fields': ['poznamka']}), # ] # list_display = ['reseni', 'soubor', 'timestamp'] # list_filter = ['reseni', 'timestamp'] # search_fields = [] # # admin.site.register(PrilohaReseni, PrilohaReseniAdmin) ### Reseni class ReseniAdmin(VersionAdmin): form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['problem', 'resitel'], fields=['problem', 'resitel']) fieldsets = [ (None, {'fields': ['problem', 'resitel', 'forma', 'body', 'cislo_body', 'timestamp']}), (u'Poznámky', {'fields': ['poznamka']}), ] readonly_fields = ['timestamp'] list_display = ['problem', 'resitel', 'forma', 'body', 'timestamp', 'cislo_body'] list_filter = ['body', 'timestamp', 'forma'] search_fields = [] inlines = [PrilohaReseniInline] def get_queryset(self, request): qs = super(ReseniAdmin, self).get_queryset(request) return qs.select_related('resitel', 'problem', 'cislo_body') admin.site.register(Reseni, ReseniAdmin) ### Problem from autocomplete_light.contrib.taggit_field import TaggitField, TaggitWidget class ProblemAdminForm(forms.ModelForm): text_zadani = forms.CharField(widget=CKEditorWidget(), required=False, **field_labels(Problem, 'text_zadani')) text_reseni = forms.CharField(widget=CKEditorWidget(), required=False, **field_labels(Problem, 'text_reseni')) text_org = forms.CharField(widget=CKEditorWidget(), required=False, **field_labels(Problem, 'text_org')) zamereni = TaggitField(widget=TaggitWidget('TagAutocomplete'), required=False) autor = UserModelChoiceField(User.objects.filter(is_staff=True)) opravovatel = UserModelChoiceField(User.objects.filter(is_staff=True), required=False) class Meta: model = Problem exclude = [] class ProblemAdmin(VersionAdmin): form = ProblemAdminForm fieldsets = [ (None, {'fields': ['nazev', 'typ', 'stav', 'autor', 'zamereni', 'body', 'timestamp', 'import_dakos_id']}), (u'Vydání', {'fields': ['cislo_zadani', 'kod', 'cislo_reseni', 'opravovatel',]}), (None, {'fields': ['text_zadani', 'text_reseni', 'text_org',]}), ] readonly_fields = ['timestamp', 'import_dakos_id'] list_select_related = True search_fields = ['nazev', 'text_zadani', 'text_reseni', 'text_org'] view_on_site = Problem.verejne_url def get_queryset(self, request): qs = super(ProblemAdmin, self).get_queryset(request) return qs.select_related('autor', 'opravovatel', 'cislo_zadani', 'cislo_reseni') def pocet_reseni(self, obj): return obj.pocet_reseni class ProblemNavrhAdmin(ProblemAdmin): list_display = ['nazev', 'typ', 'stav', 'autor', 'timestamp'] list_filter = ['typ', 'zamereni', 'timestamp', 'stav'] def get_queryset(self, request): qs = super(ProblemNavrhAdmin, self).get_queryset(request) return qs.filter(stav__in=[Problem.STAV_NAVRH, Problem.STAV_SMAZANY]) get_form = get_form_predvypln_autora create_modeladmin(ProblemNavrhAdmin, Problem, 'ProblemNavrh', verbose_name=u'Problém (návrh)', verbose_name_plural=u'Problémy (návrhy)') class ProblemZadanyAdmin(ProblemAdmin): list_display = ['nazev', 'typ', 'autor', 'opravovatel', 'kod', 'cislo_zadani', 'pocet_reseni', 'verejne'] list_filter = ['typ', 'cislo_zadani__cislo', 'cislo_zadani__rocnik'] inlines = [ReseniKProblemuInline] def get_queryset(self, request): qs = super(ProblemZadanyAdmin, self).get_queryset(request) return qs.filter(stav=Problem.STAV_ZADANY).annotate(pocet_reseni=Count('reseni')) get_form = get_form_predvypln_autora create_modeladmin(ProblemZadanyAdmin, Problem, 'ProblemZadany', verbose_name=u'Problém (zadaný)', verbose_name_plural=u'Problémy (zadané)') #admin.site.register(Problem, ProblemAdmin) ### Soustredeni class SoustredeniAdminForm(forms.ModelForm): text = forms.CharField(widget=CKEditorWidget(), required=False, **field_labels(Soustredeni, 'text')) class Meta: model = Soustredeni exclude = [] class SoustredeniAdmin(VersionAdmin): form = SoustredeniAdminForm fieldsets = [ (None, {'fields': ['rocnik', 'misto', 'typ', 'verejne_db', 'exportovat', 'text']}), (u'Data', {'fields': ['datum_zacatku', 'datum_konce']}), ] list_display = ['rocnik', 'misto', 'datum_zacatku', 'typ', 'exportovat', 'verejne'] inlines = [Soustredeni_UcastniciInline] list_filter = ['typ', 'rocnik'] view_on_site = Soustredeni.verejne_url actions = [ make_set_action('verejne_db', True, u'Zveřejnit soustředění'), make_set_action('verejne_db', False, u'Skrýt (zneveřejnit) soustředění'), make_set_action('exportovat', True, u'Nastavit pro AESOP export'), make_set_action('exportovat', False, u'Skrýt pro AESOP export'), ] admin.site.register(Soustredeni, SoustredeniAdmin) ### Novinky class NovinkyAdminForm(forms.ModelForm): text = forms.CharField(widget=CKEditorWidget(), required=False, **field_labels(Novinky, 'text')) autor = UserModelChoiceField(User.objects.filter(is_staff=True)) class Meta: model = Novinky exclude = [] def zverejnit_novinky(modeladmin, request, queryset): ''' zverejni vybrane novinky ''' for novinka in queryset: novinka.zverejneno = True novinka.save() zverejnit_novinky.short_description = 'Zveřejnit vybané novinky' def zneverejnit_novinky(modeladmin, request, queryset): ''' zneverejni vybrane novinky''' for novinka in queryset: novinka.zverejneno = False novinka.save() zneverejnit_novinky.short_description = 'Zneveřejnit vybrané novinky' class NovinkyAdmin(VersionAdmin): form = NovinkyAdminForm list_display = ['datum', 'autor', 'text', 'zverejneno', 'obrazek'] actions = [zverejnit_novinky, zneverejnit_novinky] get_form = get_form_predvypln_autora admin.site.register(Novinky, NovinkyAdmin) ### Organizator def jmeno_organizatora(obj): ''' vraci jmeno organizatora ''' jmeno = obj.user.first_name if obj.prezdivka: jmeno = jmeno + ' "' + obj.prezdivka + '"' jmeno = jmeno + ' ' + obj.user.last_name if jmeno == ' ': # zobrazeni bezejmennych orgu return 'org' return jmeno jmeno_organizatora.short_description = 'Jméno organizátora' def je_organizator_aktivni(obj): ''' zjisti, zda-li je organizator aktivni ''' return obj.user.is_active je_organizator_aktivni.short_description = 'Aktivní' je_organizator_aktivni.boolean = True def zaktivovat_organizatory(modeladmin, request, queryset): ''' vybrane organizatory oznaci jako aktivni ''' for org in queryset: org.user.is_active = True org.user.save() zaktivovat_organizatory.short_description = 'Zaktivovat organizátory' def deaktivovat_organizatory(modeladmin, request, queryset): ''' deaktivuje vybrane organizatory ''' for org in queryset: org.user.is_active = False org.user.save() deaktivovat_organizatory.short_description = 'Deaktivovat organizátory' @admin.register(Organizator) class OrganizatorAdmin(VersionAdmin): list_filter = ['organizuje_do_roku'] list_display = [jmeno_organizatora, je_organizator_aktivni,] actions = [zaktivovat_organizatory, deaktivovat_organizatory,]