Browse Source

Merge remote branch 'origin/master' into Petr

Conflicts:
	seminar/admin.py
remotes/origin/feincms
Bc. Petr Pecha 9 years ago
parent
commit
0fa9bbe76e
  1. 25
      mamweb/settings_common.py
  2. BIN
      mamweb/static/favicon.ico
  3. 1
      mamweb/templates/admin/base_site.html
  4. 1
      mamweb/templates/base.html
  5. 3
      requirements.txt
  6. 215
      seminar/admin.py
  7. 4
      seminar/autocomplete_light_registry.py
  8. 18
      seminar/migrations/0012_remove_soustredeni_ucastnici.py
  9. 36
      seminar/migrations/0013_soustredeni_ucastnici_through_model.py
  10. 50
      seminar/migrations/0014_uprava_poznamek.py
  11. 64
      seminar/models.py
  12. 2
      seminar/urls.py
  13. 6
      seminar/views.py

25
mamweb/settings_common.py

@ -49,9 +49,11 @@ AUTHENTICATION_BACKENDS = (
)
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
'django.template.loaders.eggs.Loader'
('django.template.loaders.cached.Loader', (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
'django.template.loaders.eggs.Loader'
)),
)
MIDDLEWARE_CLASSES = (
@ -95,17 +97,22 @@ INSTALLED_APPS = (
'solo',
'ckeditor',
'taggit',
'autocomplete_light',
# MaMweb
'mamweb',
'seminar',
# Prvni:
'autocomplete_light',
'admin_tools',
'admin_tools.theming',
'admin_tools.menu',
'admin_tools.dashboard',
# Admin upravy:
# 'material',
# 'material.admin',
# 'admin_tools',
# 'admin_tools.theming',
# 'admin_tools.menu',
# 'admin_tools.dashboard',
'flat',
'django.contrib.admin',
)

BIN
mamweb/static/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

1
mamweb/templates/admin/base_site.html

@ -2,6 +2,7 @@
{% load staticfiles %}
{% block extrahead %}
<link rel="shortcut icon" href="{% static 'favicon.ico' %}" type="image/x-icon">
<script src="{% static 'js/jquery-1.11.1.js' %}"></script>
{% include 'autocomplete_light/static.html' %}
{% endblock %}

1
mamweb/templates/base.html

@ -4,6 +4,7 @@
<head>
<title>{% block title %}Seminář M&amp;M{% endblock title %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="{% static 'favicon.ico' %}" type="image/x-icon">
{% render_block "css" %}
<link href="{% static 'css/bootstrap-theme.css' %}" rel="stylesheet">
<link href="{% static 'css/bootstrap.css' %}" rel="stylesheet">

3
requirements.txt

@ -17,9 +17,10 @@ django-sekizai==0.8.1
django-countries==3.2
django-solo==1.1.0
django-ckeditor==4.4.7
django-admin-tools==0.5.2
django-flat-theme==0.9.3
django-taggit==0.14.0
django-autocomplete-light==2.1.1
# django-admin-tools==0.5.2
# debug tools/extensions

215
seminar/admin.py

@ -1,31 +1,115 @@
# -*- coding: utf-8 -*-
from django.contrib import admin
from django import forms
from django.forms import widgets
import reversion
from solo.admin import SingletonModelAdmin
from ckeditor.widgets import CKEditorWidget
from django.db.models import Count
from django.db import models
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici
import autocomplete_light
### Nastaveni
### Globální nastavení
admin.site.register(Nastaveni, SingletonModelAdmin)
### Skola
class SkolaAdmin(reversion.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']}),
]
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
admin.site.register(Skola, SkolaAdmin)
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(reversion.VersionAdmin):
@ -37,33 +121,55 @@ class ResitelAdmin(reversion.VersionAdmin):
(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']
list_display = ['jmeno', 'prijmeni', 'user', 'pohlavi_muz', 'skola', 'rok_maturity', 'pocet_reseni']
list_filter = ['pohlavi_muz', 'rok_maturity', 'zasilat']
search_fields = ['jmeno', 'prijmeni', 'ulice', 'user', '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(reversion.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(reversion.VersionAdmin):
fieldsets = [
(None, {'fields': ['cislo', 'rocnik', 'verejne_db']}),
(None, {'fields': ['cislo', 'rocnik', 'verejne_db', 'poznamka']}),
(u'Data', {'fields': ['datum_vydani', 'datum_deadline']}),
]
list_display = ['kod', 'rocnik', 'cislo', 'datum_vydani', 'datum_deadline', 'verejne']
list_filter = ['rocnik']
view_on_site = Cislo.verejne_url
def get_queryset(self, request):
qs = super(CisloAdmin, self).get_queryset(request)
return qs.select_related('rocnik')
admin.site.register(Cislo, CisloAdmin)
class CisloInline(admin.StackedInline):
model = Cislo
fields = ['cislo', 'datum_vydani', 'datum_deadline', 'verejne_db']
readonly_fields = ['cislo']
extra = 0
### Rocnik
class RocnikAdmin(reversion.VersionAdmin):
@ -78,55 +184,50 @@ admin.site.register(Rocnik, RocnikAdmin)
### PrilohaReseni
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)
class PrilohaReseniInline(admin.StackedInline):
model = PrilohaReseni
fields = ['timestamp', 'soubor', 'poznamka']
readonly_fields = ['timestamp']
extra = 1
# 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(reversion.VersionAdmin):
form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['problem'], fields=['problem'])
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']
list_display = ['problem', 'resitel', 'forma', 'body', 'timestamp', 'cislo_body']
list_filter = ['body', 'timestamp', 'forma']
search_fields = []
inlines = [PrilohaReseniInline]
admin.site.register(Reseni, ReseniAdmin)
def get_queryset(self, request):
qs = super(ReseniAdmin, self).get_queryset(request)
return qs.select_related('resitel', 'problem', 'cislo_body')
class ReseniInline(admin.TabularInline):
model = Reseni
fields = ['resitel', 'forma', 'body', 'cislo_body', 'timestamp', 'poznamka']
readonly_fields = ['poznamka', 'resitel', 'timestamp', 'cislo_body', 'resitel', 'forma']
extra = 0
admin.site.register(Reseni, ReseniAdmin)
### Problem
from autocomplete_light.contrib.taggit_field import TaggitField, TaggitWidget
#TODO: Autocomplete autor/opravovatel
class ProblemAdminForm(forms.ModelForm):
text_problemu = forms.CharField(widget=CKEditorWidget())
text_problemu_org = forms.CharField(widget=CKEditorWidget())
zamereni = TaggitField(widget=TaggitWidget('TagAutocomplete'))
class Meta:
model = Problem
exclude = []
@ -135,17 +236,24 @@ class ProblemAdmin(reversion.VersionAdmin):
form = ProblemAdminForm
fieldsets = [
(None, {'fields': ['nazev', 'typ', 'stav', 'autor', 'zamereni', 'body', 'timestamp']}),
(u'Vydání', {'fields': ['cislo_zadani', 'kod', 'cislo_reseni', 'opravovatel']}),
(u'Texty', {'fields': ['text_problemu', 'text_problemu_org']}),
(u'Vydání', {'fields': ['cislo_zadani', 'kod', 'cislo_reseni', 'opravovatel', 'text_problemu']}),
(None, {'fields': ['text_problemu_org']}),
]
readonly_fields = ['timestamp']
list_display = ['nazev', 'typ', 'kod', 'stav', 'autor', 'opravovatel', 'verejne', 'cislo_zadani']
list_display = ['nazev', 'typ', 'kod', 'stav', 'autor', 'opravovatel', 'verejne', 'cislo_zadani', 'pocet_reseni']
list_select_related = True
list_filter = ['typ', 'stav', 'timestamp']
search_fields = ['nazev', 'kod', 'text_problemu_org', 'text_problemu']
inlines = [ReseniInline]
inlines = [ReseniKProblemuInline]
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').annotate(pocet_reseni=Count('reseni'))
def pocet_reseni(self, obj):
return obj.pocet_reseni
admin.site.register(Problem, ProblemAdmin)
@ -157,8 +265,9 @@ class SoustredeniAdmin(reversion.VersionAdmin):
(u'Data', {'fields': ['datum_zacatku', 'datum_konce']}),
]
list_display = ['rocnik', 'misto', 'datum_zacatku', 'verejne']
inlines = [Soustredeni_UcastniciInline]
list_filter = ['rocnik']
view_on_site = Soustredeni.verejne_url
# TODO: UcastNaSoustredeni jako inline
admin.site.register(Soustredeni, SoustredeniAdmin)

4
seminar/autocomplete_light_registry.py

@ -3,6 +3,10 @@
import autocomplete_light
from models import Skola, Resitel, Problem
from taggit.models import Tag
autocomplete_light.register(Tag)
class SkolaAutocomplete(autocomplete_light.AutocompleteModelBase):

18
seminar/migrations/0012_remove_soustredeni_ucastnici.py

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('seminar', '0011_alter_timestamp_def'),
]
operations = [
migrations.RemoveField(
model_name='soustredeni',
name='ucastnici',
),
]

36
seminar/migrations/0013_soustredeni_ucastnici_through_model.py

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('seminar', '0012_remove_soustredeni_ucastnici'),
]
operations = [
migrations.CreateModel(
name='Soustredeni_Ucastnici',
fields=[
('id', models.AutoField(serialize=False, primary_key=True)),
('poznamka', models.CharField(default=b'', help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', max_length=64, verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)),
('resitel', models.ForeignKey(verbose_name='\u0159e\u0161itel', to='seminar.Resitel')),
('soustredeni', models.ForeignKey(verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni')),
],
options={
'ordering': ['soustredeni', 'resitel'],
'db_table': 'seminar_soustredeni_ucastnici',
'verbose_name': '\xda\u010dast na soust\u0159ed\u011bn\xed',
'verbose_name_plural': '\xda\u010dasti na soust\u0159ed\u011bn\xed',
},
bases=(models.Model,),
),
migrations.AddField(
model_name='soustredeni',
name='ucastnici',
field=models.ManyToManyField(help_text='Seznam \xfa\u010dastn\xedk\u016f soust\u0159ed\u011bn\xed', to='seminar.Resitel', verbose_name='\xfa\u010dastn\xedci soust\u0159ed\u011bn\xed', through='seminar.Soustredeni_Ucastnici'),
preserve_default=True,
),
]

50
seminar/migrations/0014_uprava_poznamek.py

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('seminar', '0013_soustredeni_ucastnici_through_model'),
]
operations = [
migrations.AlterModelOptions(
name='problem',
options={'ordering': ['nazev'], 'verbose_name': 'Probl\xe9m', 'verbose_name_plural': 'Probl\xe9my'},
),
migrations.AlterModelOptions(
name='reseni',
options={'ordering': ['problem_id', 'resitel_id'], 'verbose_name': '\u0158e\u0161en\xed', 'verbose_name_plural': '\u0158e\u0161en\xed'},
),
migrations.AlterModelOptions(
name='skola',
options={'ordering': ['mesto', 'nazev'], 'verbose_name': '\u0160kola', 'verbose_name_plural': '\u0160koly'},
),
migrations.AddField(
model_name='cislo',
name='poznamka',
field=models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u010d\xedslu (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='problem',
name='text_problemu_org',
field=models.TextField(verbose_name='neve\u0159ejn\xe9 zad\xe1n\xed a organiz\xe1torsk\xe9 a pozn\xe1mky', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='reseni',
name='poznamka',
field=models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u0159e\u0161en\xed (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='soustredeni_ucastnici',
name='poznamka',
field=models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True),
preserve_default=True,
),
]

64
seminar/models.py

@ -10,6 +10,8 @@ from django.utils.encoding import python_2_unicode_compatible
from django.utils.encoding import force_unicode
from django.utils.text import slugify
from django.core.urlresolvers import reverse
from django.core.cache import cache
from django_countries.fields import CountryField
from solo.models import SingletonModel
@ -19,7 +21,6 @@ import reversion
from seminar.utils import roman
# TODO společná báze (admin url, url, veřejné, ...)
class SeminarModelBase(models.Model):
class Meta:
@ -54,6 +55,7 @@ class Skola(SeminarModelBase):
db_table = 'seminar_skoly'
verbose_name = u'Škola'
verbose_name_plural = u'Školy'
ordering = ['mesto', 'nazev']
# Interní ID
id = models.AutoField(primary_key = True)
@ -229,6 +231,16 @@ class Rocnik(SeminarModelBase):
def verejne_url(self):
return reverse('seminar_rocnik', kwargs={'pk': self.id})
@classmethod
def cached_rocnik(cls, r_id):
name = 'rocnik_%s' % (r_id, )
c = cache.get(name)
if c is None:
c = cls.objects.get(id=r_id)
cache.set(name, c, 300)
return c
@reversion.register(ignore_duplicate_revisions=True)
@python_2_unicode_compatible
@ -256,12 +268,17 @@ class Cislo(SeminarModelBase):
verejne_db = models.BooleanField(u'číslo zveřejněno', db_column='verejne', default=False)
poznamka = models.TextField(u'neveřejná poznámka', blank=True,
help_text=u'Neveřejná poznámka k číslu (plain text)')
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(),))
# Potenciální DB HOG, pokud by se ročník neckešoval
r = Rocnik.cached_rocnik(self.rocnik_id)
return force_unicode(u'%s.%s' % (r.rocnik, self.cislo, ))
def verejne(self):
return self.verejne_db
@ -294,6 +311,7 @@ class Problem(SeminarModelBase):
db_table = 'seminar_problemy'
verbose_name = u'Problém'
verbose_name_plural = u'Problémy'
ordering = ['nazev']
# Interní ID
id = models.AutoField(primary_key = True)
@ -327,7 +345,7 @@ class Problem(SeminarModelBase):
zamereni = TaggableManager(verbose_name=u'zaměření', help_text='Zaměření M/F/I/O problému, příp. další tagy', blank=True)
text_problemu_org = models.TextField(u'organizátorský (neveřejný) text', blank=True)
text_problemu_org = models.TextField(u'neveřejné zadání a organizátorské a poznámky', blank=True)
text_problemu = models.TextField(u'veřejný text zadání a řešení', blank=True)
@ -354,7 +372,7 @@ class Problem(SeminarModelBase):
u'"DOZ:xxx" (MAMOPER.MM_DOZ), "ZAD:rocnik.cislo.uloha.typ" (MAMOPER.MM_ZADANIA), "ULOHA:xxx" (MAMOPER.MM_ULOHY)'))
def __str__(self):
return force_unicode(u'%s (%s)' % (self.nazev, self.stav))
return force_unicode(u'%s' % (self.nazev, ))
def kod_v_rocniku(self):
if self.typ == self.TYP_ULOHA:
@ -379,7 +397,7 @@ class Reseni(SeminarModelBase):
db_table = 'seminar_reseni'
verbose_name = u'Řešení'
verbose_name_plural = u'Řešení'
ordering = ['problem', 'resitel']
ordering = ['problem_id', 'resitel_id']
# Interní ID
id = models.AutoField(primary_key = True)
@ -405,10 +423,11 @@ class Reseni(SeminarModelBase):
forma = models.CharField(u'forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False, default=FORMA_PAPIR)
poznamka = models.TextField(u'neveřejná poznámka', blank=True,
help_text=u'Neveřejná poznámka k řešení (plain text, editace v detailu řešení)')
help_text=u'Neveřejná poznámka k řešení (plain text)')
def __str__(self):
return force_unicode(u"%s: %s (%sb)" % (self.resitel.plne_jmeno(), self.problem.nazev, self.body))
# NOTE: Potenciální DB HOG (bez select_related)
# PrilohaReseni method
@ -418,7 +437,7 @@ def generate_filename(self, filename):
fname = "%s_%s" % (
timezone.now().strftime('%Y-%m-%d-%H:%M'),
clean)
return os.path.join(settings.SEMINAR_RESENI_DIRNAME, datedir, fname)
return os.path.join(settings.SEMINAR_RESENI_DIR, datedir, fname)
@reversion.register(ignore_duplicate_revisions=True)
@ -474,10 +493,10 @@ class Soustredeni(SeminarModelBase):
help_text=u'Místo (název obce, volitelně též objektu')
ucastnici = models.ManyToManyField(Resitel, verbose_name=u'účastníci soustředění',
help_text=u'Seznam účastníků soustředění', db_table='seminar_soustredeni_ucastnici')
help_text=u'Seznam účastníků soustředění', through='Soustredeni_Ucastnici')
def __str__(self):
return force_unicode(u'%s (%s)' % (self.misto, self.datum_zacatek))
return force_unicode(u'%s (%s)' % (self.misto, self.datum_zacatku))
def verejne(self):
return self.verejne_db
@ -487,6 +506,30 @@ class Soustredeni(SeminarModelBase):
return reverse('seminar_soustredeni', kwargs={'pk': self.id})
@python_2_unicode_compatible
class Soustredeni_Ucastnici(models.Model):
class Meta:
db_table = 'seminar_soustredeni_ucastnici'
verbose_name = u'Účast na soustředění'
verbose_name_plural = u'Účasti na soustředění'
ordering = ['soustredeni', 'resitel']
# Interní ID
id = models.AutoField(primary_key = True)
resitel = models.ForeignKey(Resitel, verbose_name=u'řešitel')
soustredeni = models.ForeignKey(Soustredeni, verbose_name=u'soustředění')
poznamka = models.TextField(u'neveřejná poznámka', blank=True,
help_text=u'Neveřejná poznámka k účasti (plain text)')
def __str__(self):
return force_unicode(u'%s na %s' % (self.resitel, self.soustredeni, ))
# NOTE: Poteciální DB HOG bez select_related
@python_2_unicode_compatible
class VysledkyBase(SeminarModelBase):
@ -507,6 +550,7 @@ class VysledkyBase(SeminarModelBase):
def __str__(self):
return force_unicode(u"%s: %sb (%s)" % (self.resitel.plne_jmeno(), self.body, str(self.cislo)))
# NOTE: DB HOG (ale nepouzivany)
@python_2_unicode_compatible
class VysledkyZaCislo(VysledkyBase):
@ -517,6 +561,7 @@ class VysledkyZaCislo(VysledkyBase):
managed = False
def __str__(self):
# NOTE: DB HOG (ale nepouzivany)
return force_unicode(u"%s: %sb (za %s)" % (self.resitel.plne_jmeno(), self.body, str(self.cislo)))
@ -531,6 +576,7 @@ class VysledkyKCislu(VysledkyBase):
body_celkem = models.IntegerField(u'body celkem do čísla', db_column='body_celkem')
def __str__(self):
# NOTE: DB HOG (ale nepouzivany)
return force_unicode(u"%s: %sb / %sb (do %s)" % (self.resitel.plne_jmeno(), self.body, self.body_celkem, str(self.cislo)))

2
seminar/urls.py

@ -5,6 +5,8 @@ urlpatterns = patterns('',
url(r'^rocnik/(?P<pk>\d+)/$', views.RocnikView.as_view(), name='seminar_rocnik'),
url(r'^cislo/(?P<pk>\d+)/$', views.CisloView.as_view(), name='seminar_cislo'),
url(r'^problem/(?P<pk>\d+)/$', views.ProblemView.as_view(), name='seminar_problem'),
url(r'^soustredeni/(?P<pk>\d+)/$', views.SoustredeniView.as_view(), name='seminar_soustredeni'),
url(r'^zadani/$', views.AktualniZadaniView, name='seminar_aktualni_zadani'),
url(r'^aesop-export/mam-rocnik-(?P<prvni_rok>\d+)\.csv$', export.ExportRocnikView.as_view(), name='seminar_export_rocnik'),

6
seminar/views.py

@ -2,7 +2,7 @@ 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, Reseni, VysledkyKCislu, Nastaveni, Rocnik
from .models import Problem, Cislo, Reseni, VysledkyKCislu, Nastaveni, Rocnik, Soustredeni
def AktualniZadaniView(request):
@ -16,6 +16,10 @@ class RocnikView(generic.DetailView):
model = Rocnik
template_name = 'seminar/rocnik.html'
class SoustredeniView(generic.DetailView):
model = Soustredeni
template_name = 'seminar/soustredeni.html'
class ProblemView(generic.DetailView):
model = Problem
template_name = 'seminar/problem.html'

Loading…
Cancel
Save