From 14d834209c0fd4bdc40004e7df4e3d46d92877fe Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Tue, 23 Apr 2019 21:32:39 +0200 Subject: [PATCH 1/4] Novy model kompletni. --- seminar/models.py | 80 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/seminar/models.py b/seminar/models.py index 10d05395..99bbcc78 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -104,7 +104,7 @@ class Skola(SeminarModelBase): blank=True, null=True) def __str__(self): - return force_unicode(u'%s, %s, %s' % (self.nazev, self.ulice, self.mesto)) + return force_unicode(u'%s, %s, %s' % (self.nazev, self.ulice, self.mesto)) @reversion.register(ignore_duplicates=True) @python_2_unicode_compatible @@ -1066,6 +1066,84 @@ class Text(SeminarModelBase): 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 + root = models.ForeignKey('self', + null = True, + blank = False, + on_delete = models.SET_NULL, # Vrcholy s null kořenem jsou sirotci bez ročníku + first_child = models.ForeignKey('self', + null = True, + blank = True, + on_delete=models.SET_NULL, + verbose_name="první potomek") + succ = models.ForeignKey('self', + null = True, + blank = True, + on_delete=models.SET_NULL, + verbose_name="další element na stejné úrovni") + +class RocnikNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_rocnik' + verbose_name = 'Ročník (Node)' + verbose_name_plural = 'Ročníky (Node)' + rocnik = models.ForeignKey(Rocnik, + on_delete = models.PROTECT, # Pokud chci mazat ročník, musím si Node pořešit ručně + verbose_name = "ročník") + +class CisloNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_cislo' + verbose_name = 'Číslo (Node)' + verbose_name_plural = 'Čísla (Node)' + cislo = models.ForeignKey(Cislo, + on_delete = models.PROTECT, # Pokud chci mazat číslo, musím si Node pořešit ručně + verbose_name = "číslo") + +class MezicisloNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_mezicislo' + verbose_name = 'Mezičíslo (Node)' + verbose_name_plural = 'Mezičísla (Node)' + +class TemaVCisleNode(TreeNode): + """ Obsahuje příspěvky k tématu v daném čísle """ + class Meta: + db_table = 'seminar_nodes_temavcisle' + verbose_name = 'Téma v čísle (Node)' + verbose_name_plural = 'Témata v čísle (Node)' + tema = models.ForeignKey(Tema, + on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně + verbose_name = "téma v čísle") + +class KonferaNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_konfera' + verbose_name = 'Konfera (Node)' + verbose_name_plural = 'Konfery (Node)' + +class ClanekNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_clanek' + verbose_name = 'Článek (Node)' + verbose_name_plural = 'Články (Node)' + +class UlohaNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_uloha' + verbose_name = 'Úloha (Node)' + verbose_name_plural = 'Úlohy (Node)' + +class TextNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_obsah' + verbose_name = 'Text (Node)' + verbose_name_plural = 'Text (Node)' + text = models.ForeignKey(Text, + on_delete=models.PROTECT, + verbose_name = 'text') ## FIXME: Logiku přesunout do views. #@python_2_unicode_compatible From 1b8d98af5b13836c2cb333282e4f7971a4d37de8 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Tue, 23 Apr 2019 21:33:27 +0200 Subject: [PATCH 2/4] Schema noveho modelu. --- Schema_new.dia | Bin 14742 -> 14335 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Schema_new.dia b/Schema_new.dia index 3e11da786b2d40aa343fd2d08ae362d79a54fa47..d7a38dbdaa369012ffa94b3dddbf5ebc54f737be 100644 GIT binary patch literal 14335 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 From 90dc3a04f568bbbc9efa5c70de6f46be48c67bb5 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Tue, 23 Apr 2019 22:25:18 +0200 Subject: [PATCH 3/4] 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') From b678337955afe5bdb7a1c2a022d70bd173e5743e Mon Sep 17 00:00:00 2001 From: LEdoian Date: Wed, 1 May 2019 00:46:59 +0200 Subject: [PATCH 4/4] =?UTF-8?q?Fix=20clashes=20v=20*Node=20v=C4=9Bcech?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/seminar/models.py b/seminar/models.py index 48ac2e60..97fee733 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1095,6 +1095,7 @@ class TreeNode(models.Model): class Meta: abstract = True root = models.ForeignKey('self', + related_name="potomci_set", null = True, blank = False, on_delete = models.SET_NULL, # Vrcholy s null kořenem jsou sirotci bez ročníku @@ -1105,6 +1106,7 @@ class TreeNode(models.Model): on_delete=models.SET_NULL, verbose_name="první potomek") succ = models.ForeignKey('self', + related_name="prev", null = True, blank = True, on_delete=models.SET_NULL,