Browse Source

Merge branch 'data_migrations' of gimli.ms.mff.cuni.cz:/akce/mam/git/mamweb into data_migrations

export_seznamu_prednasek
Martin Z. (Zimamazim) 6 years ago
parent
commit
98ac569245
  1. 21
      mamweb/urls.py
  2. 733
      seminar/admin.py
  3. 174
      seminar/testutils.py

21
mamweb/urls.py

@ -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.conf.urls.i18n import i18n_patterns
from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.contrib import admin from django.contrib import admin
from django.conf import settings from django.conf import settings
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from django import views from django import views
from django.urls import path # As per docs.
urlpatterns = [ urlpatterns = [
# Admin a nastroje # Admin a nastroje
url('admin/', admin.site.urls), # NOQA path('admin/', admin.site.urls), # NOQA
url('ckeditor/', include('ckeditor_uploader.urls')), path('ckeditor/', include('ckeditor_uploader.urls')),
url('autocomplete/', include('autocomplete_light.urls')), path('autocomplete/', include('autocomplete_light.urls')),
# Seminarova aplikace (ma vlastni podadresare) # Seminarova aplikace (ma vlastni podadresare)
url('', include('seminar.urls')), path('', include('seminar.urls')),
# Korekturovaci aplikace (ma vlastni podadresare) # Korekturovaci aplikace (ma vlastni podadresare)
url('', include('korektury.urls')), path('', include('korektury.urls')),
# Prednaskova aplikace (ma vlastni podadresare) # Prednaskova aplikace (ma vlastni podadresare)
url('', include('prednasky.urls')), path('', include('prednasky.urls')),
# Comments (interni i verejne) # Comments (interni i verejne)
url('comments_dj/', include('django_comments.urls')), path('comments_dj/', include('django_comments.urls')),
url('comments_fl/', include('fluent_comments.urls')), path('comments_fl/', include('fluent_comments.urls')),
] ]
# This is only needed when using runserver. # This is only needed when using runserver.
if settings.DEBUG: if settings.DEBUG:
urlpatterns += [ 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}), {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
] ]
urlpatterns += staticfiles_urlpatterns() urlpatterns += staticfiles_urlpatterns()

733
seminar/admin.py

@ -1,701 +1,36 @@
# -*- coding: utf-8 -*-
from django.contrib import admin 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)

174
seminar/testutils.py

@ -7,7 +7,7 @@ import django.contrib.auth
from django.db import transaction from django.db import transaction
import unidecode import unidecode
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Osoba, Organizator, Prijemce, Tema, Uloha, Konfera, KonferaNode, RocnikNode from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Osoba, Organizator, Prijemce, Tema, Uloha, Konfera, KonferaNode, TextNode, UlohaVzorakNode, RocnikNode, CisloNode, TemaVCisleNode
from django.contrib.flatpages.models import FlatPage from django.contrib.flatpages.models import FlatPage
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
@ -60,7 +60,7 @@ def gen_osoby(rnd, size):
datum_registrace = datetime.date(rnd.randint(2019, 2029), datum_registrace = datetime.date(rnd.randint(2019, 2029),
rnd.randint(1, 12), rnd.randint(1, 28)))) rnd.randint(1, 12), rnd.randint(1, 28))))
#TODO pridat foto male a velke. Jak? #TODO pridat foto male a velke. Jak?
# Pavel tvrdí, že to necháme a přidáme až do adminu # Pavel tvrdí, že to necháme a přidáme až do adminu
return osoby return osoby
@ -148,7 +148,7 @@ def gen_ulohy_do_cisla(rnd, cislo, organizatori, resitele, slovnik_cisel, size):
"sporné", "nepopsatelně jednoduché", "pokud jste na to nepřišli," "sporné", "nepopsatelně jednoduché", "pokud jste na to nepřišli,"
"tak jste fakt hloupí"] "tak jste fakt hloupí"]
if cislo >= 3: if cislo >= 3: #TODO nagenerovat i nody!!!
for pi in range(1, ((size + 1) // 2) + 1): for pi in range(1, ((size + 1) // 2) + 1):
poc_op = rnd.randint(1, 4) # počet opravovatelů poc_op = rnd.randint(1, 4) # počet opravovatelů
poc_oboru = rnd.randint(1, 2) poc_oboru = rnd.randint(1, 2)
@ -208,23 +208,23 @@ def gen_ulohy_do_cisla(rnd, cislo, organizatori, resitele, slovnik_cisel, size):
return return
def gen_soustredeni(rnd, resitele, organizatori): def gen_soustredeni(rnd, resitele, organizatori):
soustredeni = [] soustredeni = []
for _ in range(1, 10): #FIXME Tu range si změňte jak chcete, nevím, co přesně znamená size (asi Anet?) for _ in range(1, 10): #FIXME Tu range si změňte jak chcete, nevím, co přesně znamená size (asi Anet?)
datum_zacatku=datetime.date(rnd.randint(2000, 2020), rnd.randint(1, 12), rnd.randint(1, 28)) datum_zacatku=datetime.date(rnd.randint(2000, 2020), rnd.randint(1, 12), rnd.randint(1, 28))
working_sous = Soustredeni.objects.create( working_sous = Soustredeni.objects.create(
rocnik=Rocnik.objects.order_by('?').first(), rocnik=Rocnik.objects.order_by('?').first(),
verejne_db=rnd.choice([True, False]), verejne_db=rnd.choice([True, False]),
misto=rnd.choice(['Kremrolovice', 'Indiánov', 'U zmzliny', 'Vafláreň', 'Větrník', 'Horní Rakvička', 'Dolní cheesecake']), misto=rnd.choice(['Kremrolovice', 'Indiánov', 'U zmzliny', 'Vafláreň', 'Větrník', 'Horní Rakvička', 'Dolní cheesecake']),
typ=rnd.choice(['jarni', 'podzimni', 'vikend']), typ=rnd.choice(['jarni', 'podzimni', 'vikend']),
datum_zacatku=datum_zacatku, datum_zacatku=datum_zacatku,
datum_konce=datum_zacatku + datetime.timedelta(days=7)) datum_konce=datum_zacatku + datetime.timedelta(days=7))
for res in rnd.sample(resitele, min(len(resitele), 20)): for res in rnd.sample(resitele, min(len(resitele), 20)):
Soustredeni_Ucastnici.objects.create(resitel=res, soutredeni=working_sous) Soustredeni_Ucastnici.objects.create(resitel=res, soutredeni=working_sous)
for org in rnd.sample(organizatori, min(len(organizatori), 20)): for org in rnd.sample(organizatori, min(len(organizatori), 20)):
Soustredeni_Organizatori.objects.create(organizator=org, soutredeni=working_sous) Soustredeni_Organizatori.objects.create(organizator=org, soutredeni=working_sous)
working_sous.save() working_sous.save()
soustredeni.append(working_sous) soustredeni.append(working_sous)
return soustredeni return soustredeni
def gen_rocniky(last_rocnik, size): def gen_rocniky(last_rocnik, size):
rocniky = [] rocniky = []
@ -237,24 +237,24 @@ def gen_rocniky(last_rocnik, size):
return rocniky return rocniky
def gen_konfery(rnd, reseni, organizatori, ucastnici, soustredeni): def gen_konfery(rnd, reseni, organizatori, ucastnici, soustredeni):
konfery = [] konfery = []
for _ in range(1, size): #FIXME Tu range si změňte jak chcete, nevím, co přesně znamená size (asi Anet?) for _ in range(1, size): #FIXME Tu range si změňte jak chcete, nevím, co přesně znamená size (asi Anet?)
konfera = Konfera.objects.create( konfera = Konfera.objects.create(
nazev=rnd.choice(['Pozorování', 'Zkoumání', 'Modelování', 'Počítání', 'Zkoušení']) + rnd.choice([' vlastností', ' jevů', ' charakteristik']) + rnd.choice([' vektorových prostorů', ' kinetické terorie látek', ' molekulární biologie', ' syntentických stromů']), nazev=rnd.choice(['Pozorování', 'Zkoumání', 'Modelování', 'Počítání', 'Zkoušení']) + rnd.choice([' vlastností', ' jevů', ' charakteristik']) + rnd.choice([' vektorových prostorů', ' kinetické terorie látek', ' molekulární biologie', ' syntentických stromů']),
anotace=lorem.paragraph(), anotace=lorem.paragraph(),
abstrakt=lorem.paragraph(), abstrakt=lorem.paragraph(),
organizator=rnd.choice(organizatori), organizator=rnd.choice(organizatori),
soustredeni=rnd.choice(soustredeni), soustredeni=rnd.choice(soustredeni),
reseni=rnd.choice(reseni), reseni=rnd.choice(reseni),
typ_prezentace=rnd.choice(['veletrh', 'prezentace'])) typ_prezentace=rnd.choice(['veletrh', 'prezentace']))
for res in rnd.sample(ucastnici, min(len(ucastnici), rnd.randint(3, 6))): for res in rnd.sample(ucastnici, min(len(ucastnici), rnd.randint(3, 6))):
Konfery_Ucastnici.objects.create(resitel=res, konfera=konfera) Konfery_Ucastnici.objects.create(resitel=res, konfera=konfera)
konfery.append(konfera) konfery.append(konfera)
konfera.save() konfera.save()
konferanode = KonferaNode.objects.create(konfera=konfera) konferanode = KonferaNode.objects.create(konfera=konfera)
konferanode.save() konferanode.save()
return konfery return konfery
def gen_cisla(rocniky): def gen_cisla(rocniky):
slovnik_rocnik_cisla = {} slovnik_rocnik_cisla = {}
@ -368,52 +368,53 @@ def gen_ulohy_k_tematum(rocniky, slovnik_rocnik_cisla, slovnik_rocnik_temata): #
for rocnik in rocniky: for rocnik in rocniky:
slovnik_cisel = slovnik_rocnik_cisla[rocnik] slovnik_cisel = slovnik_rocnik_cisla[rocnik]
slovnik_temat = slovnik_rocnik_temata[rocnik] slovnik_temat = slovnik_rocnik_temata[rocnik]
for cislo in slovnik_cisel: for cislo in slovnik_cisel:
syn = cislo.CisloNode.first_child syn = cislo.CisloNode.first_child
while syn != None: while syn != None:
tema = syn.tema if type(syn) != TemaVCisleNode
for i in range(1, rnd.randint(1, 4)) continue
poc_op = rnd.randint(1, 4) else:
poc_oboru = rnd.randint(1, 2) tema = syn.tema
p = Uloha.objects.create( for i in range(1, rnd.randint(1, 4))
nazev=": ".join([tema.nazev, poc_op = rnd.randint(1, 4)
"úloha {}.".format(i)]), poc_oboru = rnd.randint(1, 2)
nadproblem=tema, p = Uloha.objects.create(
stav=Problem.STAV_ZADANY, nazev=": ".join([tema.nazev,
zamereni=tema.zamereni, "úloha {}.".format(i)]),
autor=tema.autor, nadproblem=tema,
garant=tema.garant, stav=Problem.STAV_ZADANY,
opravovatele=rnd.sample(organizatori, poc_op), zamereni=tema.zamereni,
kod=str(i), autor=tema.autor,
cislo_zadani=cislo, garant=tema.garant,
cislo_reseni=slovnik_cisel[cislo.cislo+2], opravovatele=rnd.sample(organizatori, poc_op),
cislo_deadline=slovnik_cisel[cislo.cislo+2], kod=str(i),
max_body = rnd.randint(1, 8) cislo_zadani=cislo,
) cislo_reseni=slovnik_cisel[cislo.cislo+2],
p.zadani = " ".join([rnd.choice(sloveso), rnd.choice(koho), cislo_deadline=slovnik_cisel[cislo.cislo+2],
rnd.choice(ceho), rnd.choice(jmeno), rnd.choice(kde)]) max_body = rnd.randint(1, 8)
)
#Tomův pokus o opravu bugu: p.zadani = " ".join([rnd.choice(sloveso), rnd.choice(koho),
text_vzoraku = Text.objects.create( rnd.choice(ceho), rnd.choice(jmeno), rnd.choice(kde)])
na_web = rnd.choice(reseni),
do_cisla = rnd.choice(reseni) text_vzoraku = Text.objects.create(
) na_web = rnd.choice(reseni),
vzorak = TextNode.objects.create(text = text_vzoraku) do_cisla = rnd.choice(reseni)
uloha_vzorak = UlohaVzorakNode.objects.create(uloha=p, first_child = vzorak) )
p.UlohaVzorakNode = uloha_vzorak vzorak = TextNode.objects.create(text = text_vzoraku)
uloha_vzorak = UlohaVzorakNode.objects.create(uloha=p, first_child = vzorak)
#p.vzorak = " - ".join([p.zadani, rnd.choice(reseni)]) p.UlohaVzorakNode = uloha_vzorak
p.save() p.save()
syn = syn.succ
syn = syn.succ
# vytvor text
# vytvor TemaVCisleNode # vytvor text
if (rnd.randint(1, 3) % 3 == 0): # vytvor TemaVCisleNode
# vytvor mezicislo Node if (rnd.randint(1, 3) % 3 == 0):
pass # vytvor mezicislo Node
pass
@transaction.atomic @transaction.atomic
def create_test_data(size = 6, rnd = None): def create_test_data(size = 6, rnd = None):
@ -482,11 +483,6 @@ def create_test_data(size = 6, rnd = None):
# generování úloh k tématům ve všech číslech # generování úloh k tématům ve všech číslech
gen_ulohy_k_tematum(rocniky, slovnik_rocnik_cisla, slovnik_rocnik_temata) gen_ulohy_k_tematum(rocniky, slovnik_rocnik_cisla, slovnik_rocnik_temata)
# nagenerovat k tématu úlohy a Nody pro vsechna cisla
# FIXME: misto typu ruzne typy objektu a vnoreni do sebe # FIXME: misto typu ruzne typy objektu a vnoreni do sebe
# TODO: vytvorit temata s ruznymi vlakny # TODO: vytvorit temata s ruznymi vlakny
# TODO: nagenerovat starsim rocnikum pohadku # TODO: nagenerovat starsim rocnikum pohadku

Loading…
Cancel
Save