From 90dc3a04f568bbbc9efa5c70de6f46be48c67bb5 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Tue, 23 Apr 2019 22:25:18 +0200 Subject: [PATCH] Opravy poli podle noveho modelu. --- seminar/admin.py | 62 +++--- seminar/autocomplete_light_registry.py | 6 +- seminar/models.py | 274 +++++++++++++------------ seminar/views.py | 8 +- 4 files changed, 178 insertions(+), 172 deletions(-) diff --git a/seminar/admin.py b/seminar/admin.py index 29363f68..1f919ef0 100644 --- a/seminar/admin.py +++ b/seminar/admin.py @@ -13,7 +13,7 @@ from django.core.urlresolvers 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, Prispevek, Pohadka, Konfera +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 @@ -124,9 +124,9 @@ class ProblemInline(admin.TabularInline): class ReseniKProblemuInline(admin.TabularInline): - form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['resitel'], fields=['resitel']) + form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['resitele'], fields=['resitele']) model = Reseni - fields = ['resitel', 'forma', 'body', 'cislo_body', 'timestamp', 'poznamka'] + fields = ['resitele', 'forma', 'body', 'cislo_body', 'timestamp', 'poznamka'] readonly_fields = ['timestamp'] extra = 0 formfield_overrides = { @@ -136,7 +136,7 @@ class ReseniKProblemuInline(admin.TabularInline): def get_queryset(self, request): qs = super(ReseniKProblemuInline, self).get_queryset(request) - return qs.select_related('problem', 'cislo_body', 'resitel') + 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): @@ -323,13 +323,13 @@ admin.site.register(Rocnik, RocnikAdmin) ### Reseni class ReseniAdmin(VersionAdmin): - form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['problem', 'resitel'], fields=['problem', 'resitel']) + #form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['problem', 'resitele'], fields=['problem', 'resitele']) fieldsets = [ - (None, {'fields': ['problem', 'resitel', 'forma', 'body', 'cislo_body', 'timestamp']}), + (None, {'fields': ['problem', 'resitele', 'forma', 'body', 'cislo_body', 'timestamp']}), (u'Poznámky', {'fields': ['poznamka']}), ] readonly_fields = ['timestamp'] - list_display = ['problem', 'resitel', 'forma', 'body', 'timestamp', 'cislo_body'] + list_display = ['problem', 'resitele', 'forma', 'body', 'timestamp', 'cislo_body'] list_filter = ['body', 'timestamp', 'forma'] search_fields = [] inlines = [PrilohaReseniInline] @@ -337,7 +337,7 @@ class ReseniAdmin(VersionAdmin): def get_queryset(self, request): qs = super(ReseniAdmin, self).get_queryset(request) - return qs.select_related('resitel', 'problem', 'cislo_body') + return qs.select_related('resitele', 'problem', 'cislo_body') admin.site.register(Reseni, ReseniAdmin) @@ -350,7 +350,7 @@ class PohadkaAdminForm(forms.ModelForm): exclude = [] autor = UserModelChoiceField(User.objects.filter(is_staff=True)) uloha = forms.ModelChoiceField( - Problem.objects.filter(typ=Problem.TYP_ULOHA) + Uloha.objects.all() ) def __init__(self, *args, **kwargs): @@ -402,15 +402,15 @@ 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')) + #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 = [] + exclude = ['nadproblem'] def __init__(self, *args, **kwargs): super(ProblemAdminForm, self).__init__(*args, **kwargs) @@ -476,7 +476,8 @@ class ProblemNavrhAdmin(ProblemAdmin): 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)') +#FIXME +#create_modeladmin(ProblemNavrhAdmin, Problem, 'ProblemNavrh', verbose_name=u'Problém (návrh)', verbose_name_plural=u'Problémy (návrhy)') class ProblemZadanyAdmin(ProblemAdmin): @@ -529,27 +530,28 @@ class ProblemZadanyAdmin(ProblemAdmin): get_form = get_form_predvypln_autora -create_modeladmin(ProblemZadanyAdmin, Problem, 'ProblemZadany', verbose_name=u'Problém (zadaný)', verbose_name_plural=u'Problémy (zadané)') +#FIXME +#create_modeladmin(ProblemZadanyAdmin, Problem, 'ProblemZadany', verbose_name=u'Problém (zadaný)', verbose_name_plural=u'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) +#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 diff --git a/seminar/autocomplete_light_registry.py b/seminar/autocomplete_light_registry.py index 13318877..95364337 100644 --- a/seminar/autocomplete_light_registry.py +++ b/seminar/autocomplete_light_registry.py @@ -117,7 +117,7 @@ class ProblemAutocomplete(autocomplete_light.AutocompleteModelBase): popisek = "CHYBA" return popisek else: - return u"%s (%s, %s)" % (p.nazev, p.typ, p.stav) + return u"%s (%s)" % (p.nazev, p.stav) attrs={ # This will set the input placeholder attribute: @@ -133,6 +133,8 @@ class ProblemAutocomplete(autocomplete_light.AutocompleteModelBase): 'class': 'modern-style', } -autocomplete_light.register(ProblemAutocomplete) +#FIXME Nefunguje, nevime proc +#autocomplete_light.register(ProblemAutocomplete) + diff --git a/seminar/models.py b/seminar/models.py index 99bbcc78..6810bab7 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -45,67 +45,6 @@ class SeminarModelBase(models.Model): def verejne_url(self): return None -# -# Mělo by být částečně vytaženo z Aesopa -# viz https://ovvp.mff.cuni.cz/wiki/aesop/export-skol. -# - -@reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Skola(SeminarModelBase): - - class Meta: - db_table = 'seminar_skoly' - verbose_name = u'Škola' - verbose_name_plural = u'Školy' - ordering = ['mesto', 'nazev'] - - # Interní ID - id = models.AutoField(primary_key = True) - - # Aesopi ID "izo:..." nebo "aesop:..." - # NULL znamená v exportu do aesopa "ufo" - aesop_id = models.CharField(u'Aesop ID', max_length=32, blank=True, default='', - help_text=u'Aesopi ID typu "izo:..." nebo "aesop:..."') - - # IZO školy (jen české školy) - izo = models.CharField(u'IZO', max_length=32, blank=True, - help_text=u'IZO školy (jen české školy)') - - # Celý název školy - nazev = models.CharField(u'název', max_length=256, - help_text=u'Celý název školy') - - # Zkraceny nazev pro zobrazení ve výsledkovce, volitelné. - # Není v Aesopovi, musíme vytvářet sami. - kratky_nazev = models.CharField(u'zkrácený název', max_length=256, blank=True, - help_text="Zkrácený název pro zobrazení ve výsledkovce") - - # Ulice může být jen číslo - ulice = models.CharField(u'ulice', max_length=256) - - mesto = models.CharField(u'město', max_length=256) - - psc = models.CharField(u'PSČ', max_length=32) - - # ISO 3166-1 dvojznakovy kod zeme velkym pismem (CZ, SK) - # Ekvivalentní s CharField(max_length=2, default='CZ', ...) - stat = CountryField(u'stát', default='CZ', - help_text=u'ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)') - - # Jaké vzdělání škpla poskytuje? - je_zs = models.BooleanField(u'základní stupeň', default=True) - je_ss = models.BooleanField(u'střední stupeň', default=True) - - poznamka = models.TextField(u'neveřejná poznámka', blank=True, - help_text=u'Neveřejná poznámka ke škole (plain text)') - - kontaktni_osoba = models.ForeignKey(Osoba, verbose_name=u'Kontaktní osoba', - blank=True, null=True) - - def __str__(self): - return force_unicode(u'%s, %s, %s' % (self.nazev, self.ulice, self.mesto)) - @reversion.register(ignore_duplicates=True) @python_2_unicode_compatible class Osoba(SeminarModelBase): @@ -185,6 +124,68 @@ class Osoba(SeminarModelBase): def __str__(self): return force_unicode("Osoba({})".format(self.plne_jmeno())) +# +# Mělo by být částečně vytaženo z Aesopa +# viz https://ovvp.mff.cuni.cz/wiki/aesop/export-skol. +# + +@reversion.register(ignore_duplicates=True) +@python_2_unicode_compatible +class Skola(SeminarModelBase): + + class Meta: + db_table = 'seminar_skoly' + verbose_name = u'Škola' + verbose_name_plural = u'Školy' + ordering = ['mesto', 'nazev'] + + # Interní ID + id = models.AutoField(primary_key = True) + + # Aesopi ID "izo:..." nebo "aesop:..." + # NULL znamená v exportu do aesopa "ufo" + aesop_id = models.CharField(u'Aesop ID', max_length=32, blank=True, default='', + help_text=u'Aesopi ID typu "izo:..." nebo "aesop:..."') + + # IZO školy (jen české školy) + izo = models.CharField(u'IZO', max_length=32, blank=True, + help_text=u'IZO školy (jen české školy)') + + # Celý název školy + nazev = models.CharField(u'název', max_length=256, + help_text=u'Celý název školy') + + # Zkraceny nazev pro zobrazení ve výsledkovce, volitelné. + # Není v Aesopovi, musíme vytvářet sami. + kratky_nazev = models.CharField(u'zkrácený název', max_length=256, blank=True, + help_text="Zkrácený název pro zobrazení ve výsledkovce") + + # Ulice může být jen číslo + ulice = models.CharField(u'ulice', max_length=256) + + mesto = models.CharField(u'město', max_length=256) + + psc = models.CharField(u'PSČ', max_length=32) + + # ISO 3166-1 dvojznakovy kod zeme velkym pismem (CZ, SK) + # Ekvivalentní s CharField(max_length=2, default='CZ', ...) + stat = CountryField(u'stát', default='CZ', + help_text=u'ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)') + + # Jaké vzdělání škpla poskytuje? + je_zs = models.BooleanField(u'základní stupeň', default=True) + je_ss = models.BooleanField(u'střední stupeň', default=True) + + poznamka = models.TextField(u'neveřejná poznámka', blank=True, + help_text=u'Neveřejná poznámka ke škole (plain text)') + + kontaktni_osoba = models.ForeignKey(Osoba, verbose_name=u'Kontaktní osoba', + blank=True, null=True) + + def __str__(self): + return force_unicode(u'%s, %s, %s' % (self.nazev, self.ulice, self.mesto)) + + class Prijemce(SeminarModelBase): class Meta: db_table = 'seminar_prijemce' @@ -289,6 +290,8 @@ class Resitel(SeminarModelBase): return 'Prof.' else: return 'Akad.' + def __str__(): + return(force_unicode(u"Řešitel ({})".format(self.osoba.plne_jmeno()))) @@ -448,6 +451,63 @@ class Cislo(SeminarModelBase): return None return c +@reversion.register(ignore_duplicates=True) +@python_2_unicode_compatible +class Organizator(SeminarModelBase): +# zmena dedicnosti z models.Model na SeminarModelBase, potencialni vznik bugu + + osoba = models.ForeignKey(Osoba, verbose_name=u'osoba', related_name='org', + help_text=u'osobní údaje organizátora', null=False, blank=False) + + vytvoreno = models.DateTimeField( + u'Vytvořeno', + default=timezone.now, + blank=True, + editable=False + ) + + organizuje_od = models.DateTimeField('Organizuje od', blank=False, null=False) + + organizuje_do = models.DateTimeField('Organizuje do', blank=True, null=True) + + studuje = models.CharField('Studium aj.', max_length = 256, + null = True, blank = True, + help_text=u"Např. 'Studuje Obecnou fyziku (Bc.), 3. ročník', " + u"'Vystudovala Diskrétní modely a algoritmy (Mgr.)' nebo " + u"'Přednáší na MFF'") + + strucny_popis_organizatora = models.TextField(u'Stručný popis organizátora', + null = True, blank = True) + + skola = models.CharField(u'Škola, kterou studuje', max_length = 256, null=True, blank=True, + help_text=u"Škola, např. MFF, VŠCHT, VUT, ... prostě aby se nemuselo psát do studuje" + u"školu, ale jen obor, možnost zobrazit zvlášť") + + def __str__(self): + if self.osoba.prezdivka: + return u"%s '%s' %s".format(self.osoba.jmeno, + self.osoba.prezdivka, + self.osoba.prijmeni) + else: + return u"%s %s".format(self.osoba.jmeno, self.osoba.prijmeni) + + class Meta: + verbose_name = 'Organizátor' + verbose_name_plural = 'Organizátoři' + +class Text(SeminarModelBase): + class Meta: + db_table = 'seminar_texty' + verbose_name = u'text' + verbose_name_plural = u'texty' + + na_web = models.TextField(u'text na web', blank=True, + help_text=u'Text ke zveřejnění na webu') + + do_cisla = models.TextField(u'text do čísla', blank=True, + help_text=u'Text ke zveřejnění v čísle') + + # obrázky mají návaznost opačným směrem (vazba z druhé strany) @reversion.register(ignore_duplicates=True) @python_2_unicode_compatible @@ -466,7 +526,7 @@ class Problem(SeminarModelBase): nazev = models.CharField(u'název', max_length=256) # Problém má podproblémy - nadproblem = models.ForeignKey(Problem, verbose_name=u'nadřazený problém', + nadproblem = models.ForeignKey('self', verbose_name=u'nadřazený problém', related_name='nadproblem', null=True, blank=True) STAV_NAVRH = 'navrh' @@ -621,7 +681,7 @@ class Reseni(SeminarModelBase): # Interní ID id = models.AutoField(primary_key = True) - # Ke každé dvojici řešní a problém existuje nanejvýš jedno hodnocení, doplnění vazby. + # Ke každé dvojici řešení a problém existuje nanejvýš jedno hodnocení, doplnění vazby. problem = models.ManyToManyField(Problem, verbose_name=u'problém', help_text=u'Problém', through='Hodnoceni') @@ -670,7 +730,7 @@ class Hodnoceni(SeminarModelBase): class Meta: db_table = 'seminar_hodnoceni' verbose_name = u'Hodnocení' - verbose_name_plular = u'Hodnocení' + verbose_name_plural = u'Hodnocení' # Interní ID id = models.AutoField(primary_key = True) @@ -705,21 +765,17 @@ class Hodnoceni(SeminarModelBase): # neprojdou pak migrace. Takže rozlišení funkcí generujících názvy souboru # podle adresáře řešíme takto. -## -## FIXME: Budeme řešit později, pokud to bude potřeba. -#def generate_filename_konfera(self, filename): -# return os.path.join( -# settings.SEMINAR_KONFERY_DIR, -# aux_generate_filename(self, filename) -# ) +def generate_filename_konfera(self, filename): + return os.path.join( + settings.SEMINAR_KONFERY_DIR, + aux_generate_filename(self, filename) + ) -## -## FIXME: Budeme řešit později, pokud to bude potřeba. -#def generate_filename(self, filename): -# return os.path.join( -# settings.SEMINAR_RESENI_DIR, -# aux_generate_filename(self, filename) -# ) +def generate_filename(self, filename): + return os.path.join( + settings.SEMINAR_RESENI_DIR, + aux_generate_filename(self, filename) + ) @reversion.register(ignore_duplicates=True) @@ -793,49 +849,6 @@ class Pohadka(SeminarModelBase): return force_unicode(uryvek) -@reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Organizator(SeminarModelBase): -# zmena dedicnosti z models.Model na SeminarModelBase, potencialni vznik bugu - - osoba = models.ForeignKey(Osoba, verbose_name=u'osoba', related_name='org' - help_text=u'osobní údaje organizátora', null=False, blank=False) - - vytvoreno = models.DateTimeField( - u'Vytvořeno', - default=timezone.now, - blank=True, - editable=False - ) - - organizuje_od = models.DateTimeField('Organizuje od', blank=False, null=False) - - organizuje_do = models.DateTimeField('Organizuje do', blank=True, null=True) - - studuje = models.CharField('Studium aj.', max_length = 256, - null = True, blank = True, - help_text=u"Např. 'Studuje Obecnou fyziku (Bc.), 3. ročník', " - "'Vystudovala Diskrétní modely a algoritmy (Mgr.)' nebo " - "'Přednáší na MFF'") - - strucny_popis_organizatora = models.TextField(u'Stručný popis organizátora', - null = True, blank = True) - - skola = models.CharField(u'Škola, kterou studuje', max_length = 256, null=True, blank=True, - help_text=u"Škola, např. MFF, VŠCHT, VUT, ... prostě aby se nemuselo psát do studuje" - "školu, ale jen obor, možnost zobrazit zvlášť") - - def __str__(self): - if self.osoba.prezdivka: - return u"%s '%s' %s".format(self.osoba.jmeno, - self.osoba.prezdivka, - self.osoba.prijmeni) - else: - return u"%s %s".format(self.osoba.jmeno, self.osoba.prijmeni) - - class Meta: - verbose_name = 'Organizátor' - verbose_name_plural = 'Organizátoři' @reversion.register(ignore_duplicates=True) @@ -1042,8 +1055,9 @@ class Obrazek(SeminarModelBase): na_web = models.ImageField(u'obrázek na web', upload_to='obrazky/%Y/%m/%d/', null=True, blank=True) - text = models.ForeignKey(Text, verbose_name='text', help_text=u'text, ve kterém - se obrázek vyskytuje', null=False, blank=False) + text = models.ForeignKey(Text, verbose_name='text', + help_text=u'text, ve kterém se obrázek vyskytuje', + null=False, blank=False) do_cisla_barevny = models.FileField(u'barevný obrázek do čísla', help_text = u'Barevná verze obrázku do čísla', @@ -1053,19 +1067,6 @@ class Obrazek(SeminarModelBase): help_text = u'Černobílá verze obrázku do čísla', upload_to = 'obrazky/%Y/%m/%d/', blank=True, null=True) -class Text(SeminarModelBase): - class Meta: - db_table = 'seminar_texty' - verbose_name = u'text' - verbose_name_plular = u'texty' - - na_web = models.TextField(u'text na web', blank=True, - help_text=u'Text ke zveřejnění na webu') - - do_cisla = models.TextField(u'text do čísla', blank=True, - help_text=u'Text ke zveřejnění v čísle') - - # obrázky mají návaznost opačným směrem (vazba z druhé strany) class TreeNode(models.Model): class Meta: abstract = True @@ -1073,6 +1074,7 @@ class TreeNode(models.Model): null = True, blank = False, on_delete = models.SET_NULL, # Vrcholy s null kořenem jsou sirotci bez ročníku + verbose_name="kořen stromu") first_child = models.ForeignKey('self', null = True, blank = True, diff --git a/seminar/views.py b/seminar/views.py index bbb46e81..a98ef653 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -11,8 +11,8 @@ from django.db.models import Q from django.views.decorators.csrf import ensure_csrf_cookie from django.contrib.auth import authenticate, login -from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Prispevek -from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva +from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka +#from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from . import utils from .unicodecsv import UnicodeWriter from .forms import NameForm @@ -145,8 +145,8 @@ class StareNovinkyView(generic.ListView): # Organizatori def aktivniOrganizatori(rok=date.today().year): return Organizator.objects.exclude( - organizuje_do_roku__isnull=False, - organizuje_do_roku__lt=rok + organizuje_do__isnull=False, + organizuje_do__lt=rok ).order_by('user__first_name')