Martin Z. (Zimamazim)
5 years ago
3 changed files with 130 additions and 798 deletions
@ -1,37 +1,38 @@ |
|||
from django.conf.urls import * # NOQA |
|||
from django.urls import path, include |
|||
from django.conf.urls.i18n import i18n_patterns |
|||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns |
|||
from django.contrib import admin |
|||
from django.conf import settings |
|||
from django.views.generic.base import TemplateView |
|||
from django import views |
|||
from django.urls import path # As per docs. |
|||
|
|||
urlpatterns = [ |
|||
|
|||
# Admin a nastroje |
|||
url('admin/', admin.site.urls), # NOQA |
|||
url('ckeditor/', include('ckeditor_uploader.urls')), |
|||
url('autocomplete/', include('autocomplete_light.urls')), |
|||
path('admin/', admin.site.urls), # NOQA |
|||
path('ckeditor/', include('ckeditor_uploader.urls')), |
|||
path('autocomplete/', include('autocomplete_light.urls')), |
|||
|
|||
# Seminarova aplikace (ma vlastni podadresare) |
|||
url('', include('seminar.urls')), |
|||
path('', include('seminar.urls')), |
|||
|
|||
# Korekturovaci aplikace (ma vlastni podadresare) |
|||
url('', include('korektury.urls')), |
|||
path('', include('korektury.urls')), |
|||
|
|||
# Prednaskova aplikace (ma vlastni podadresare) |
|||
url('', include('prednasky.urls')), |
|||
path('', include('prednasky.urls')), |
|||
|
|||
# Comments (interni i verejne) |
|||
url('comments_dj/', include('django_comments.urls')), |
|||
url('comments_fl/', include('fluent_comments.urls')), |
|||
path('comments_dj/', include('django_comments.urls')), |
|||
path('comments_fl/', include('fluent_comments.urls')), |
|||
|
|||
] |
|||
|
|||
# This is only needed when using runserver. |
|||
if settings.DEBUG: |
|||
urlpatterns += [ |
|||
url('media/<str:path>', views.static.serve, # NOQA |
|||
path('media/<path:path>', views.static.serve, # NOQA |
|||
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}), |
|||
] |
|||
urlpatterns += staticfiles_urlpatterns() |
|||
|
@ -1,701 +1,36 @@ |
|||
# -*- 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_uploader.widgets import CKEditorUploadingWidget |
|||
from django.db.models import Count |
|||
from django.db import models |
|||
from django.utils.safestring import mark_safe |
|||
from django.urls import reverse |
|||
|
|||
from django.contrib.auth.models import User |
|||
|
|||
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Novinky, Organizator, Pohadka, Konfera, Uloha |
|||
from autocomplete_light import shortcuts as autocomplete_light |
|||
|
|||
|
|||
class UserModelChoiceField(forms.ModelChoiceField): |
|||
"""Vlastní ModelChoiceField pro uživatele. Zobrazí kromě loginu i jméno. |
|||
""" |
|||
def label_from_instance(self, obj): |
|||
return "{} ({})".format(obj.get_full_name(), obj.username) |
|||
|
|||
def get_form_predvypln_autora(self, request, obj=None, *args, **kwargs): |
|||
"""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): |
|||
""" |
|||
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 = ['osoba_jmeno', 'osoba_prijmeni', 'skola', 'osoba_mesto', 'rok_maturity', ] |
|||
readonly_fields = ['osoba_jmeno', 'osoba_prijmeni', 'skola', 'osoba_mesto', 'rok_maturity', ] |
|||
extra = 0 |
|||
view_on_site = False |
|||
|
|||
def osoba_jmeno(self, obj): |
|||
return obj.osoba.jmeno |
|||
|
|||
def osoba_prijmeni(self, obj): |
|||
return obj.osoba.prijmeni |
|||
|
|||
def osoba_mesto(self, obj): |
|||
return obj.osoba.mesto |
|||
|
|||
def has_add_permission(self, req): return False |
|||
|
|||
|
|||
class CisloInline(admin.TabularInline): |
|||
model = Cislo |
|||
fields = ['cislo', |
|||
'datum_vydani', 'datum_deadline', 'datum_deadline_soustredeni', |
|||
'verejne_db', 'poznamka'] |
|||
readonly_fields = ['cislo'] |
|||
extra = 0 |
|||
formfield_overrides = { |
|||
models.TextField: {'widget': forms.TextInput}, |
|||
} |
|||
view_on_site = Cislo.verejne_url |
|||
|
|||
def has_add_permission(self, req): return False |
|||
|
|||
|
|||
class PrilohaReseniInline(admin.StackedInline): |
|||
model = PrilohaReseni |
|||
fields = ['vytvoreno', 'soubor', 'poznamka'] |
|||
readonly_fields = ['vytvoreno'] |
|||
formfield_overrides = { |
|||
models.TextField: {'widget': forms.TextInput}, |
|||
} |
|||
view_on_site = False |
|||
|
|||
extra = 0 |
|||
|
|||
|
|||
class ProblemInline(admin.TabularInline): |
|||
model = Problem |
|||
fields = ['kod', 'nazev', 'autor', 'garant', 'opravovatele', 'stav'] |
|||
formfield_overrides = { |
|||
models.TextField: {'widget': forms.TextInput}, |
|||
} |
|||
view_on_site = Problem.verejne_url |
|||
|
|||
extra = 0 |
|||
|
|||
|
|||
class ReseniKProblemuInline(admin.TabularInline): |
|||
form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['resitele'], fields=['resitele']) |
|||
model = Reseni |
|||
fields = ['resitele', 'forma', 'body', 'cislo_body', 'timestamp', 'poznamka'] |
|||
readonly_fields = ['timestamp'] |
|||
extra = 0 |
|||
formfield_overrides = { |
|||
models.TextField: {'widget': forms.TextInput}, |
|||
} |
|||
view_on_site = False |
|||
|
|||
def get_queryset(self, request): |
|||
qs = super(ReseniKProblemuInline, self).get_queryset(request) |
|||
return qs.select_related('problem', 'cislo_body', 'resitele') |
|||
|
|||
# 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 = ['cas_doruceni', 'problem'] |
|||
extra = 0 |
|||
formfield_overrides = { |
|||
models.TextField: {'widget': forms.TextInput}, |
|||
} |
|||
view_on_site = False |
|||
|
|||
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') |
|||
|
|||
|
|||
class Soustredeni_OrganizatoriInline(admin.TabularInline): |
|||
form = autocomplete_light.modelform_factory(Soustredeni_Organizatori, autocomplete_fields=['organizator'], fields=['organizator'],) |
|||
model = Soustredeni_Organizatori |
|||
fields = ['organizator', 'poznamka', ] |
|||
extra = 0 |
|||
formfield_overrides = { |
|||
models.TextField: {'widget': forms.TextInput}, |
|||
} |
|||
|
|||
def get_queryset(self, request): |
|||
qs = super(Soustredeni_OrganizatoriInline, self).get_queryset(request) |
|||
return qs.select_related('organizator', 'soustredeni') |
|||
|
|||
### Resitel |
|||
|
|||
class ResitelAdmin(VersionAdmin): |
|||
form = autocomplete_light.modelform_factory(Resitel, autocomplete_fields=['skola'], fields=['skola']) |
|||
fk_name = 'osoba' |
|||
fieldsets = [ |
|||
(None, {'fields': ['jmeno', 'prijmeni', 'user']}), |
|||
('Škola', {'fields': ['skola', 'rok_maturity']}), |
|||
('Seminář', {'fields': ['datum_souhlasu_udaje', 'datum_souhlasu_zasilani', 'datum_prihlaseni', 'zasilat']}), |
|||
('Osobní údaje', {'fields': ['pohlavi_muz', 'datum_narozeni', 'email', 'telefon']}), |
|||
('Adresa', {'fields': ['ulice', 'mesto', 'psc', 'stat']}), |
|||
] |
|||
list_display = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__user', 'osoba__pohlavi_muz', 'skola', 'rok_maturity', 'pocet_reseni'] |
|||
list_filter = ['osoba__pohlavi_muz', 'rok_maturity', 'zasilat'] |
|||
search_fields = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__ulice', 'osoba__mesto', 'osoba__email'] |
|||
# inlines = [ReseniKResiteliInline] # FIXME: |
|||
view_on_site = False |
|||
|
|||
def osoba__jmeno(self, obj): |
|||
return obj.osoba.jmeno |
|||
|
|||
def osoba__prijmeni(self, obj): |
|||
return obj.osoba.prijmeni |
|||
|
|||
def osoba__user(self, obj): |
|||
return obj.osoba.user |
|||
|
|||
def osoba__pohlavi_muz(self, obj): |
|||
return obj.osoba.pohlavi_muz |
|||
|
|||
def osoba__ulice(self, obj): |
|||
return obj.osoba.ulice |
|||
|
|||
def osoba__mesto(self, obj): |
|||
return obj.osoba.mesto |
|||
|
|||
def osoba__email(self, obj): |
|||
return obj.osoba.email |
|||
|
|||
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']}), |
|||
('Interní ID', {'fields': ['aesop_id', 'izo'], 'classes': ['collapse']}), |
|||
('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] |
|||
view_on_site = False |
|||
|
|||
admin.site.register(Skola, SkolaAdmin) |
|||
|
|||
|
|||
### Cislo |
|||
|
|||
class CisloAdmin(VersionAdmin): |
|||
fieldsets = [ |
|||
(None, { |
|||
'fields': [ |
|||
'cislo', |
|||
'rocnik', |
|||
'verejne_db', |
|||
'verejna_vysledkovka', |
|||
'faze', |
|||
'poznamka', |
|||
'pdf' |
|||
] |
|||
}), |
|||
('Data', {'fields': ['datum_vydani', 'datum_deadline', |
|||
'datum_deadline_soustredeni']}), |
|||
] |
|||
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, 'Zveřejnit číslo'), |
|||
make_set_action('verejne_db', False, 'Skrýt (zneveřejnit) číslo'), |
|||
make_set_action('verejna_vysledkovka', True, 'Zveřejnit výsledkovku'), |
|||
make_set_action('verejna_vysledkovka', False, 'Skrýt (zneveřejnit) výsledkovku'), |
|||
] |
|||
#inlines = [ProblemInline] |
|||
|
|||
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, 'Nastavit pro AESOP export'), |
|||
make_set_action('exportovat', False, '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']}), |
|||
# ('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', 'resitele'], fields=['problem', 'resitele']) |
|||
fieldsets = [ |
|||
(None, {'fields': ['problem__set', 'resitele__set', 'forma', 'cas_doruceni']}), |
|||
('Poznámky', {'fields': ['poznamka']}), |
|||
] |
|||
readonly_fields = ['cas_doruceni'] |
|||
list_display = [ResitelInline, 'forma', 'cas_doruceni'] |
|||
list_filter = ['cas_doruceni', 'forma'] |
|||
search_fields = [] |
|||
inlines = [PrilohaReseniInline] # FIXME: odmazáno ProblemInline,ResitelInline |
|||
view_on_site = False |
|||
|
|||
def get_queryset(self, request): |
|||
qs = super(ReseniAdmin, self).get_queryset(request) |
|||
return qs.select_related('resitele', 'problem', 'cislo_body') |
|||
|
|||
admin.site.register(Reseni, ReseniAdmin) |
|||
|
|||
|
|||
### Pohádka |
|||
|
|||
class PohadkaAdminForm(forms.ModelForm): |
|||
class Meta: |
|||
model = Pohadka |
|||
exclude = [] |
|||
autor = UserModelChoiceField(User.objects.filter(is_staff=True)) |
|||
uloha = forms.ModelChoiceField( |
|||
Uloha.objects.all() |
|||
) |
|||
|
|||
def __init__(self, *args, **kwargs): |
|||
super(PohadkaAdminForm, self).__init__(*args, **kwargs) |
|||
instance = getattr(self, 'instance', None) |
|||
|
|||
# viz ProblemAdminForm.__init__ |
|||
if instance and instance.pk: |
|||
if instance.uloha and instance.uloha.cislo_zadani: |
|||
if instance.uloha.cislo_zadani.faze != 'admin': |
|||
self.fields['text'].widget.attrs['readonly'] = True |
|||
|
|||
|
|||
class PohadkaAdmin(VersionAdmin): |
|||
form = PohadkaAdminForm |
|||
view_on_site = False |
|||
|
|||
def get_kod_ulohy(self, obj): |
|||
return obj.uloha.kod_v_rocniku() |
|||
get_kod_ulohy.short_description = 'Kód úlohy' |
|||
|
|||
def get_rocnik(self, obj): |
|||
return obj.uloha.cislo_zadani.rocnik.rocnik |
|||
get_rocnik.short_description = 'Ročník' |
|||
|
|||
list_display = [ |
|||
'__str__', |
|||
'get_rocnik', |
|||
'get_kod_ulohy', |
|||
# 'uloha', |
|||
'autor' |
|||
] |
|||
|
|||
get_form = get_form_predvypln_autora |
|||
|
|||
class PohadkaKProblemuInline(admin.TabularInline): |
|||
form = PohadkaAdminForm |
|||
model = Pohadka |
|||
exclude = [] |
|||
extra = 0 |
|||
|
|||
admin.site.register(Pohadka, PohadkaAdmin) |
|||
|
|||
|
|||
### Problem |
|||
|
|||
from autocomplete_light.contrib.taggit_field import TaggitField, TaggitWidget |
|||
|
|||
|
|||
class ProblemAdminForm(forms.ModelForm): |
|||
#text_zadani = forms.CharField(widget=CKEditorUploadingWidget(), required=False, **field_labels(Problem, 'text_zadani')) |
|||
#text_reseni = forms.CharField(widget=CKEditorUploadingWidget(), required=False, **field_labels(Problem, 'text_reseni')) |
|||
#text_org = forms.CharField(widget=CKEditorUploadingWidget(), 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 = ['nadproblem'] |
|||
|
|||
def __init__(self, *args, **kwargs): |
|||
super(ProblemAdminForm, self).__init__(*args, **kwargs) |
|||
instance = getattr(self, 'instance', None) |
|||
|
|||
# Nedovol měnit název a zadání resp. řešení, pokud je cislo_zadani |
|||
# resp. cislo_reseni mimo fázi admin. |
|||
# |
|||
# Nastavení readonly fields sice vypadá lépe (nevygeneruje input tag), |
|||
# ale při ukládání změny vypíše admin nespecifikovanou chybu, která je |
|||
# způsobena zřejmě tím, že se neodešle žádná hodnota pro povinné pole |
|||
# nazev. Navíc by se smazalo nepovinné pole zadání. |
|||
# |
|||
# Toto řešení je z http://stackoverflow.com/a/325038/4786205. |
|||
# |
|||
# TODO Django 1.9: použít field s atributem disabled? |
|||
if instance and instance.pk: |
|||
if instance.cislo_zadani and instance.cislo_zadani.faze != 'admin': |
|||
# CKEditor neumí readonly ... |
|||
self.fields['text_zadani'] = forms.CharField( |
|||
widget=forms.Textarea, |
|||
required=False |
|||
) |
|||
for f in ['nazev', 'text_zadani', 'body']: |
|||
self.fields[f].widget.attrs['readonly'] = True |
|||
if instance.cislo_reseni and instance.cislo_reseni.faze != 'admin': |
|||
self.fields['text_reseni'] = forms.CharField( |
|||
widget=forms.Textarea, |
|||
required=False |
|||
) |
|||
self.fields['text_reseni'].widget.attrs['readonly'] = True |
|||
|
|||
|
|||
class ProblemAdmin(VersionAdmin): |
|||
form = ProblemAdminForm |
|||
fieldsets = [ |
|||
(None, {'fields': ['nazev', 'typ', 'stav', 'autor', 'zamereni', 'body', 'timestamp', 'import_dakos_id']}), |
|||
('Vydání', {'fields': ['kod', 'cislo_reseni', 'opravovatel',]}), |
|||
(None, {'fields': ['text_zadani', 'text_reseni', 'text_org',]}), |
|||
] |
|||
list_select_related = True |
|||
search_fields = ['nazev', 'text_zadani', 'text_reseni', 'text_org'] |
|||
view_on_site = Problem.verejne_url |
|||
ordering = ['-timestamp'] |
|||
|
|||
readonly_fields = ['timestamp', 'import_dakos_id'] |
|||
|
|||
def get_queryset(self, request): |
|||
qs = super(ProblemAdmin, self).get_queryset(request) |
|||
return qs.select_related('autor', 'opravovatel', '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 |
|||
|
|||
|
|||
#FIXME |
|||
#create_modeladmin(ProblemNavrhAdmin, Problem, 'ProblemNavrh', verbose_name='Problém (návrh)', verbose_name_plural='Problémy (návrhy)') |
|||
|
|||
|
|||
class ProblemZadanyAdmin(ProblemAdmin): |
|||
list_display = [ |
|||
'nazev', |
|||
'typ', |
|||
'cislo_zadani_link', |
|||
'cislo_reseni_link', |
|||
'autor', |
|||
'opravovatel', |
|||
'kod', |
|||
'verejne' |
|||
] |
|||
list_filter = [ |
|||
'typ', 'zamereni', 'cislo_zadani__cislo', 'cislo_zadani__rocnik' |
|||
] |
|||
|
|||
def cislo_zadani_link(self, obj): |
|||
if not obj.cislo_zadani: |
|||
return "" |
|||
return mark_safe('<a href="{}">{}</a>'.format( |
|||
reverse("admin:seminar_cislo_change", args=(obj.cislo_zadani.pk,)), |
|||
obj.cislo_zadani |
|||
)) |
|||
cislo_zadani_link.short_description = 'Číslo zadání' |
|||
|
|||
# TODO pokud se budou odkazy v adminu více používat, možná by se hodilo je |
|||
# nějak zjednodušit, např. tímto? |
|||
# https://github.com/gitaarik/django-admin-relation-links |
|||
def cislo_reseni_link(self, obj): |
|||
if not obj.cislo_reseni: |
|||
return "" |
|||
return mark_safe('<a href="{}">{}</a>'.format( |
|||
reverse("admin:seminar_cislo_change", args=(obj.cislo_reseni.pk,)), |
|||
obj.cislo_reseni |
|||
)) |
|||
cislo_reseni_link.short_description = 'Číslo řešení' |
|||
|
|||
def get_inline_instances(self, request, obj=None): |
|||
if obj and obj.typ == Problem.TYP_ULOHA: |
|||
inlines = [ReseniKProblemuInline, PohadkaKProblemuInline] |
|||
else: |
|||
inlines = [ReseniKProblemuInline] |
|||
|
|||
return [inline(self.model, self.admin_site) for inline in inlines] |
|||
|
|||
def get_queryset(self, request): |
|||
qs = super(ProblemZadanyAdmin, self).get_queryset(request) |
|||
return qs.filter(stav=Problem.STAV_ZADANY) |
|||
|
|||
get_form = get_form_predvypln_autora |
|||
|
|||
#FIXME |
|||
#create_modeladmin(ProblemZadanyAdmin, Problem, 'ProblemZadany', verbose_name='Problém (zadaný)', verbose_name_plural='Problémy (zadané)') |
|||
|
|||
#admin.site.register(Problem, ProblemAdmin) |
|||
|
|||
### Prispevek (k tematkum) |
|||
|
|||
#class PrispevekAdminForm(forms.ModelForm): |
|||
# text_org = forms.CharField(widget=CKEditorUploadingWidget(), required=False, |
|||
# **field_labels(Prispevek, 'text_org')) |
|||
# text_resitel = forms.CharField(widget=CKEditorUploadingWidget(), required=False, |
|||
# **field_labels(Prispevek, 'text_resitel')) |
|||
# |
|||
# class Meta: |
|||
# model = Prispevek |
|||
# exclude = [] |
|||
# |
|||
#class PrispevekAdmin(VersionAdmin): |
|||
# form = PrispevekAdminForm |
|||
# list_display = ['nazev', 'problem', 'reseni', 'zverejnit'] |
|||
# |
|||
#admin.site.register(Prispevek, PrispevekAdmin) |
|||
|
|||
### Soustredeni |
|||
|
|||
class SoustredeniAdminForm(forms.ModelForm): |
|||
text = forms.CharField(widget=CKEditorUploadingWidget(), 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']}), |
|||
('Data', {'fields': ['datum_zacatku', 'datum_konce']}), |
|||
] |
|||
list_display = ['rocnik', 'misto', 'datum_zacatku', 'typ', 'exportovat', 'verejne'] |
|||
inlines = [Soustredeni_UcastniciInline, Soustredeni_OrganizatoriInline] |
|||
list_filter = ['typ', 'rocnik'] |
|||
view_on_site = Soustredeni.verejne_url |
|||
actions = [ |
|||
make_set_action('verejne_db', True, 'Zveřejnit soustředění'), |
|||
make_set_action('verejne_db', False, 'Skrýt (zneveřejnit) soustředění'), |
|||
make_set_action('exportovat', True, 'Nastavit pro AESOP export'), |
|||
make_set_action('exportovat', False, 'Skrýt pro AESOP export'), |
|||
] |
|||
|
|||
admin.site.register(Soustredeni, SoustredeniAdmin) |
|||
|
|||
### Konfery |
|||
class KonferaAdminForm(forms.ModelForm): |
|||
class Meta: |
|||
model=Konfera |
|||
exclude = [] |
|||
|
|||
class KonferaAdmin(VersionAdmin): |
|||
form = KonferaAdminForm |
|||
list_filter = ['soustredeni'] |
|||
list_display = ['nazev','soustredeni','organizator','typ_prezentace'] |
|||
# inlines = [Konfera_UcastniciInline] |
|||
|
|||
admin.site.register(Konfera,KonferaAdmin) |
|||
|
|||
### Novinky |
|||
|
|||
class NovinkyAdminForm(forms.ModelForm): |
|||
text = forms.CharField(widget=CKEditorUploadingWidget(), 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'] |
|||
list_display = [jmeno_organizatora, je_organizator_aktivni,] |
|||
actions = [zaktivovat_organizatory, deaktivovat_organizatory,] |
|||
|
|||
import seminar.models as m |
|||
|
|||
admin.site.register(m.Osoba) |
|||
admin.site.register(m.Skola) |
|||
admin.site.register(m.Prijemce) |
|||
admin.site.register(m.Resitel) |
|||
admin.site.register(m.Rocnik) |
|||
admin.site.register(m.Cislo) |
|||
admin.site.register(m.Organizator) |
|||
admin.site.register(m.Soustredeni) |
|||
admin.site.register(m.Problem) |
|||
admin.site.register(m.Tema) |
|||
admin.site.register(m.Clanek) |
|||
admin.site.register(m.Text) |
|||
admin.site.register(m.Uloha) |
|||
admin.site.register(m.Reseni) |
|||
admin.site.register(m.Hodnoceni) |
|||
admin.site.register(m.PrilohaReseni) |
|||
admin.site.register(m.Pohadka) |
|||
admin.site.register(m.Konfera) |
|||
admin.site.register(m.Obrazek) |
|||
admin.site.register(m.TreeNode) |
|||
admin.site.register(m.RocnikNode) |
|||
admin.site.register(m.CisloNode) |
|||
admin.site.register(m.MezicisloNode) |
|||
admin.site.register(m.TemaVCisleNode) |
|||
admin.site.register(m.KonferaNode) |
|||
admin.site.register(m.ClanekNode) |
|||
admin.site.register(m.UlohaZadaniNode) |
|||
admin.site.register(m.PohadkaNode) |
|||
admin.site.register(m.UlohaVzorakNode) |
|||
admin.site.register(m.TextNode) |
|||
admin.site.register(m.Nastaveni) |
|||
admin.site.register(m.Novinky) |
|||
|
Loading…
Reference in new issue