diff --git a/mamweb/settings.py b/mamweb/settings.py index 84c065a3..a2e00263 100644 --- a/mamweb/settings.py +++ b/mamweb/settings.py @@ -103,7 +103,6 @@ TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.tz', 'sekizai.context_processors.sekizai', 'django.core.context_processors.static', - 'cms.context_processors.cms_settings', 'allauth.account.context_processors.account', 'allauth.socialaccount.context_processors.socialaccount', ) @@ -115,10 +114,12 @@ INSTALLED_APPS = ( 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', + 'django.contrib.sites', 'django.contrib.staticfiles', 'sekizai', 'reversion', + 'feincms', 'allauth', 'allauth.account', @@ -165,4 +166,4 @@ SOCIALACCOUNT_EMAIL_REQUIRED = True # MaM specific -SEMINAR_RESENI_DIRNAME = 'reseni' \ No newline at end of file +SEMINAR_RESENI_DIRNAME = 'reseni' diff --git a/mamweb/templates/base.html b/mamweb/templates/base.html index 4e3b83a6..34b06f60 100644 --- a/mamweb/templates/base.html +++ b/mamweb/templates/base.html @@ -1,37 +1,44 @@ {% load cms_tags staticfiles sekizai_tags menu_tags %} - + - {% block title %}This is my new project home page{% endblock title %} + {% block title %}Seminář M&M{% endblock title %} {% render_block "css" %} - - + + + + + - + {% cms_toolbar %} -
- - {% block content %} - {% endblock content %} -
- - +
+
+ Korespondenční seminář M&M +
+
+
+ Menu +
+
+ {% block content %} + {% endblock content %} +
+
+
+ + + + {% render_block "js" %} diff --git a/seminar/admin.py b/seminar/admin.py index 7c27c481..2a13c390 100644 --- a/seminar/admin.py +++ b/seminar/admin.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- from django.contrib import admin -from seminar.models import Skola, Resitel +from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni +### Skola + class SkolaAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['nazev', 'kratky_nazev']}), @@ -10,10 +12,13 @@ class SkolaAdmin(admin.ModelAdmin): (u'Adresa', {'fields': ['ulice', 'mesto', 'psc', 'stat']}), ] list_display = ['nazev', 'aesop_id', 'mesto'] + search_fields = ['nazev', 'mesto', 'ulice'] admin.site.register(Skola, SkolaAdmin) +### Resitel + class ResitelAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['jmeno', 'prijmeni', 'user']}), @@ -22,6 +27,92 @@ class ResitelAdmin(admin.ModelAdmin): (u'Osobní údaje', {'fields': ['pohlavi_muz', 'datum_narozeni', 'email', 'telefon']}), (u'Adresa', {'fields': ['ulice', 'mesto', 'psc', 'stat']}), ] - list_display = ['jmeno', 'prijmeni', 'pohlavi_muz', 'skola', 'rok_maturity'] + list_display = ['jmeno', 'prijmeni', 'user', 'pohlavi_muz', 'skola', 'rok_maturity'] + list_filter = ['pohlavi_muz', 'rok_maturity', 'zasilat'] + search_fields = ['jmeno', 'prijmeni', 'ulice', 'user', 'mesto', 'email'] admin.site.register(Resitel, ResitelAdmin) + + +### Cislo + +class CisloAdmin(admin.ModelAdmin): + fieldsets = [ + (None, {'fields': ['cislo', 'rocnik']}), + (u'Data', {'fields': ['datum_vydani', 'datum_deadline']}), + ] + list_display = ['kod', 'rocnik', 'cislo', 'datum_vydani', 'datum_deadline'] + list_filter = ['rocnik'] + +admin.site.register(Cislo, CisloAdmin) + +class CisloInline(admin.StackedInline): + model = Cislo + extra = 0 + + +### Rocnik + +class RocnikAdmin(admin.ModelAdmin): + fieldsets = [ + (None, {'fields': ['rocnik', 'prvni_rok']}), + ] + list_display = ['rocnik', 'prvni_rok'] + inlines = [CisloInline] + +admin.site.register(Rocnik, RocnikAdmin) + + +### PrilohaReseni + +class PrilohaReseniAdmin(admin.ModelAdmin): + readonly_fields = ['timestamp'] + fieldsets = [ + (None, {'fields': ['reseni', 'soubor', 'timestamp']}), + ] + list_display = ['reseni', 'soubor', 'timestamp'] + list_filter = ['reseni', 'timestamp'] + search_fields = [] + +admin.site.register(PrilohaReseni, PrilohaReseniAdmin) + +class PrilohaReseniInline(admin.StackedInline): + model = PrilohaReseni + extra = 1 + + +### Reseni + +class ReseniAdmin(admin.ModelAdmin): + readonly_fields = ['timestamp'] + fieldsets = [ + (None, {'fields': ['problem', 'resitel', 'body', 'cislo_body', 'timestamp']}), + ] + list_display = ['problem', 'resitel', 'body', 'timestamp'] + list_filter = ['problem', 'resitel', 'body', 'timestamp'] + search_fields = [] + inlines = [PrilohaReseniInline] + +admin.site.register(Reseni, ReseniAdmin) + +class ReseniInline(admin.StackedInline): + model = Reseni + extra = 0 + + +### Problem +from feincms.admin import item_editor + +class ProblemAdmin(item_editor.ItemEditor): +# readonly_fields = ['autor'] + fieldsets = [ + (None, {'fields': ['nazev', 'typ', 'stav', 'autor']}), + (u'Vydání', {'fields': ['cislo_zadani', 'kod', 'cislo_reseni', 'opravovatel']}), + item_editor.FEINCMS_CONTENT_FIELDSET, + ] + list_display = ['nazev', 'typ', 'stav', 'autor', 'kod', 'opravovatel'] + list_filter = ['typ', 'stav', 'autor', 'opravovatel'] + search_fields = ['nazev', 'autor', 'kod']#, 'text_problemu_org', 'text_problemu'] + inlines = [ReseniInline] + +admin.site.register(Problem, ProblemAdmin) diff --git a/seminar/models.py b/seminar/models.py index 7016fee2..f8f704ca 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1,14 +1,23 @@ # -*- coding: utf-8 -*- +import os +import datetime +import random + from django.db import models from django.contrib import auth from django.utils import timezone from django.conf import settings +from django.utils.encoding import python_2_unicode_compatible +from django.utils.encoding import force_unicode + +from feincms.models import Base # # Mělo by být částečně vytaženo z Aesopa # viz https://ovvp.mff.cuni.cz/wiki/aesop/export-skol. # +@python_2_unicode_compatible class Skola(models.Model): class Meta: @@ -48,10 +57,11 @@ class Skola(models.Model): stat = models.CharField(u'kód státu', max_length=2, default='CZ', help_text=u'ISO 3166-1 kód zeme velkými písmeny (CZ, SK, ...)') - def __unicode__(self): - return u'%s, %s' % (self.nazev, self.mesto) + def __str__(self): + return force_unicode(u'%s, %s' % (self.nazev, self.mesto)) +@python_2_unicode_compatible class Resitel(models.Model): class Meta: @@ -116,10 +126,14 @@ class Resitel(models.Model): stat = models.CharField(u'kód státu', max_length=2, help_text=u'ISO 3166-1 kód zeme velkými písmeny (CZ, SK, ...)', default='CZ') - def __unicode__(self): - return u'%s %s' % (self.jmeno, self.prijmeni) + def plne_jmeno(self): + return force_unicode(u'%s %s' % (self.jmeno, self.prijmeni)) + + def __str__(self): + return force_unicode(self.plne_jmeno()) +@python_2_unicode_compatible class Rocnik(models.Model): class Meta: @@ -131,9 +145,15 @@ class Rocnik(models.Model): # Interní ID id = models.AutoField(primary_key = True) - rocnik = models.IntegerField(u'číslo ročníku') + prvni_rok = models.IntegerField(u'první rok') + + rocnik = models.CharField(u'číslo ročníku', max_length=16) + + def __str__(self): + return force_unicode(u'%s (%d/%d)' % (self.rocnik, self.prvni_rok, self.prvni_rok+1)) +@python_2_unicode_compatible class Cislo(models.Model): class Meta: @@ -158,9 +178,14 @@ class Cislo(models.Model): def kod(self): return u'%s.%s' % (self.rocnik.rocnik, self.cislo) + kod.short_description = u'Kód čísla' + def __str__(self): + return force_unicode(u'%s' % (self.kod(),)) -class Problem(models.Model): + +@python_2_unicode_compatible +class Problem(Base): class Meta: db_table = 'seminar_problemy' @@ -170,6 +195,7 @@ class Problem(models.Model): # Interní ID id = models.AutoField(primary_key = True) + # Název nazev = models.CharField(u'název', max_length=256) TYP_ULOHA = 'uloha' @@ -196,33 +222,99 @@ class Problem(models.Model): ] stav = models.CharField(u'stav problému', max_length=32, choices=STAV_CHOICES, blank=False, default=STAV_NAVRH) - text_org = None +# text_problemu_org = PlaceholderField('text_problemu_org', related_name='problem_text_org', +# verbose_name=u'organizátorský (neveřejný) text') - text_verejny = None +# text_problemu = PlaceholderField('text_problemu', related_name='problem_text', +# verbose_name=u'veřejný text zadání a řešení') - zadavatel + autor = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'autor problému', related_name='autor_uloh') - opravovatel + opravovatel = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'opravovatel', null=True, blank=True, + related_name='opravovatel_uloh') kod = models.CharField(u'lokální kód', max_length=32, blank=True, default='', help_text=u'Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku') - cislo_zadani = models.ForeignKey(Cislo, verbose_name=u'číslo zadání', blank=True, null=True) - - cislo_reseni = models.ForeignKey(Cislo, verbose_name=u'číslo řešení', blank=True, null=True, - help_text=u'Číslo s řešením úlohy. Jen pri ') -# -# -# class Reseni(models.Model): -# -# class Meta: -# db_table = 'seminar_reseni' -# verbose_name = u'Řešení' -# verbose_name_plural = u'Řešení' -# ordering = ['rocnik__rocnik', 'cislo'] -# -# # Interní ID -# id = models.AutoField(primary_key = True) -# -# -# + cislo_zadani = models.ForeignKey(Cislo, verbose_name=u'číslo zadání', blank=True, null=True, related_name=u'zadane_problemy') + + cislo_reseni = models.ForeignKey(Cislo, verbose_name=u'číslo řešení', blank=True, null=True, related_name=u'resene_problemy', + help_text=u'Číslo s řešením úlohy, jen pro úlohy') + + def __str__(self): + return force_unicode(u'%s (%s)' % (self.nazev, self.stav)) + +from feincms.content.richtext.models import RichTextContent +from feincms.content.image.models import ImageContent +from feincms.content.medialibrary.models import MediaFileContent + +Problem.register_regions( + ('text_problemu', 'uveřejný text zadání a řešení'), + ('text_problemu_org', u'organizátorský (neveřejný) text') + ) +Problem.create_content_type(RichTextContent) +Problem.create_content_type( + ImageContent, + POSITION_CHOICES=( + ('default', 'Default position'), + ) + ) + + +@python_2_unicode_compatible +class Reseni(models.Model): + + class Meta: + db_table = 'seminar_reseni' + verbose_name = u'Řešení' + verbose_name_plural = u'Řešení' + ordering = ['problem', 'resitel'] + + # Interní ID + id = models.AutoField(primary_key = True) + + problem = models.ForeignKey(Problem, verbose_name=u'problém', related_name='reseni') + + resitel = models.ForeignKey(Resitel, verbose_name=u'řešitel', related_name='reseni') + + body = models.IntegerField(u'body', blank=True, null=True) + + cislo_body = models.ForeignKey(Cislo, verbose_name=u'číslo pro body', related_name='bodovana_reseni', blank=True, null=True) + + timestamp = models.DateTimeField(u'vytvořeno', auto_now=True) + + def __str__(self): + return force_unicode(u"%s: %s" % (self.resitel.plne_jmeno(), self.problem.nazev)) + + +@python_2_unicode_compatible +class PrilohaReseni(models.Model): + + class Meta: + db_table = 'seminar_priloha_reseni' + verbose_name = u'Příloha řešení' + verbose_name_plural = u'Přílohy řešení' + ordering = ['reseni', 'timestamp'] + + # Interní ID + id = models.AutoField(primary_key = True) + + reseni = models.ForeignKey(Reseni, verbose_name=u'řešení', related_name='prilohy') + + timestamp = models.DateTimeField(u'vytvořeno', auto_now=True) + + def generate_filename(self, filename): + clean = filename.replace('/','-').replace('\0', '') + datedir = datetime.datetime.now().strftime('%Y-%m') + fname = "%s_%06d_%s" % ( + datetime.datetime.now().strftime('%Y-%m-%d-%H:%M'), + random.randint(0,999999), + clean) + return os.path.join(settings.SEMINAR_RESENI_DIRNAME, datedir, fname) + + soubor = models.FileField(u'soubor', upload_to = generate_filename) + + def __str__(self): + return force_unicode(self.soubor) + + diff --git a/seminar/views.py b/seminar/views.py index 91ea44a2..44124d1e 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -1,3 +1,17 @@ -from django.shortcuts import render +from django.shortcuts import get_object_or_404, render +from django.http import HttpResponseRedirect +from django.core.urlresolvers import reverse +from django.views import generic +from .models import Problem, Cislo # Create your views here. + +class ProblemView(generic.DetailView): + model = Problem + template_name = 'seminar/problem.html' + +class CisloView(generic.DetailView): + model = Cislo + template_name = 'seminar/cislo.html' + +