Add CKEditor +configure, first tests, test data generation
This commit is contained in:
parent
065461300d
commit
0b88b8022c
7 changed files with 167 additions and 73 deletions
|
@ -90,6 +90,7 @@ INSTALLED_APPS = (
|
||||||
'reversion',
|
'reversion',
|
||||||
'django_countries',
|
'django_countries',
|
||||||
'solo',
|
'solo',
|
||||||
|
'ckeditor',
|
||||||
|
|
||||||
# MaMweb
|
# MaMweb
|
||||||
'mamweb',
|
'mamweb',
|
||||||
|
@ -97,9 +98,53 @@ INSTALLED_APPS = (
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
DEBUG_TOOLBAR_CONFIG = {
|
||||||
|
'SHOW_COLLAPSED': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
SUMMERNOTE_CONFIG = {
|
||||||
|
'iframe': False,
|
||||||
|
'airMode': False,
|
||||||
|
'attachment_require_authentication': True,
|
||||||
|
'width': '80%',
|
||||||
|
# 'height': '30em',
|
||||||
|
'toolbar': [
|
||||||
|
['style', ['style']],
|
||||||
|
['font', ['bold', 'italic', 'superscript', 'subscript', 'clear']],
|
||||||
|
['color', ['color']],
|
||||||
|
['para', ['ul', 'ol', 'paragraph']],
|
||||||
|
['table', ['table']],
|
||||||
|
['insert', ['link', 'picture', 'hr']],
|
||||||
|
['view', ['fullscreen', 'codeview']],
|
||||||
|
['help', ['help']],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
CKEDITOR_UPLOAD_PATH = "uploads/"
|
||||||
|
CKEDITOR_IMAGE_BACKEND = 'pillow'
|
||||||
|
#CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'
|
||||||
|
CKEDITOR_CONFIGS = {
|
||||||
|
'default': {
|
||||||
|
'toolbar': [
|
||||||
|
['Source', 'ShowBlocks', '-', 'Maximize'],
|
||||||
|
['Bold', 'Italic', 'Subscript', 'Superscript', '-', 'RemoveFormat'],
|
||||||
|
['NumberedList','BulletedList','-','Blockquote','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
|
||||||
|
['Link', 'Unlink', 'Anchor', '-', 'Image', 'Table', 'HorizontalRule'],
|
||||||
|
['Format'],
|
||||||
|
|
||||||
|
],
|
||||||
|
# 'toolbar': 'full',
|
||||||
|
'height': '40em',
|
||||||
|
'width': '100%',
|
||||||
|
'toolbarStartupExpanded': False
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
# MaM specific
|
# MaM specific
|
||||||
|
|
||||||
SEMINAR_RESENI_DIR = os.path.join(BASE_DIR, 'media', 'reseni')
|
SEMINAR_RESENI_DIR = os.path.join(BASE_DIR, 'media', 'reseni')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ from django.conf import settings
|
||||||
urlpatterns = i18n_patterns('',
|
urlpatterns = i18n_patterns('',
|
||||||
|
|
||||||
url(r'^admin/', include(admin.site.urls)), # NOQA
|
url(r'^admin/', include(admin.site.urls)), # NOQA
|
||||||
|
url(r'^ckeditor/', include('ckeditor.urls')),
|
||||||
url(r'^', include('seminar.urls')),
|
url(r'^', include('seminar.urls')),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ django-reversion==1.8.5
|
||||||
django-sekizai==0.8.1
|
django-sekizai==0.8.1
|
||||||
django-countries==3.2
|
django-countries==3.2
|
||||||
django-solo==1.1.0
|
django-solo==1.1.0
|
||||||
|
django-ckeditor==4.4.7
|
||||||
|
|
||||||
# debug tools/extensions
|
# debug tools/extensions
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni
|
from django import forms
|
||||||
from solo.admin import SingletonModelAdmin
|
from solo.admin import SingletonModelAdmin
|
||||||
|
from ckeditor.widgets import CKEditorWidget
|
||||||
|
|
||||||
|
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni
|
||||||
|
|
||||||
### Nastaveni
|
### Nastaveni
|
||||||
|
|
||||||
|
@ -106,7 +109,15 @@ class ReseniInline(admin.StackedInline):
|
||||||
|
|
||||||
### Problem
|
### Problem
|
||||||
|
|
||||||
|
class ProblemAdminForm(forms.ModelForm):
|
||||||
|
text_problemu = forms.CharField(widget=CKEditorWidget())
|
||||||
|
text_problemu_org = forms.CharField(widget=CKEditorWidget())
|
||||||
|
class Meta:
|
||||||
|
model = Problem
|
||||||
|
exclude = []
|
||||||
|
|
||||||
class ProblemAdmin(admin.ModelAdmin):
|
class ProblemAdmin(admin.ModelAdmin):
|
||||||
|
form = ProblemAdminForm
|
||||||
# readonly_fields = ['autor']
|
# readonly_fields = ['autor']
|
||||||
fieldsets = [
|
fieldsets = [
|
||||||
(None, {'fields': ['nazev', 'typ', 'stav', 'autor']}),
|
(None, {'fields': ['nazev', 'typ', 'stav', 'autor']}),
|
||||||
|
|
|
@ -8,6 +8,12 @@ from django.core.management.base import NoArgsCommand
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni
|
||||||
|
from seminar.tests import create_test_data
|
||||||
|
import django.contrib.auth
|
||||||
|
User = django.contrib.auth.get_user_model()
|
||||||
|
|
||||||
|
|
||||||
class Command(NoArgsCommand):
|
class Command(NoArgsCommand):
|
||||||
help = "Clear database and load testing data."
|
help = "Clear database and load testing data."
|
||||||
|
|
||||||
|
@ -18,76 +24,13 @@ class Command(NoArgsCommand):
|
||||||
os.rename(dbfile, dbfile + '.old')
|
os.rename(dbfile, dbfile + '.old')
|
||||||
self.stderr.write('Stara databaze prejmenovana na "%s"' % (dbfile + '.old'))
|
self.stderr.write('Stara databaze prejmenovana na "%s"' % (dbfile + '.old'))
|
||||||
call_command('migrate', noinput=True)
|
call_command('migrate', noinput=True)
|
||||||
self.load_testing_data()
|
self.stdout.write('Vytvarim uzivatele "admin" (heslo "admin") a pseudo-nahodna data ...')
|
||||||
|
create_test_data()
|
||||||
def load_testing_data(self):
|
self.stdout.write('Vytvoreno %d uzivatelu, %d skol, %d resitelu, %d rocniku, %d cisel, %d problemu, %d reseni.' %
|
||||||
from seminar import models as sm
|
(User.objects.count(), Skola.objects.count(), Resitel.objects.count(), Rocnik.objects.count(),
|
||||||
import django.contrib.auth
|
Cislo.objects.count(), Problem.objects.count(), Reseni.objects.count()))
|
||||||
User = django.contrib.auth.get_user_model()
|
|
||||||
|
|
||||||
self.stderr.write('Vytvarim uzivatele "admin" (heslo "admin")')
|
|
||||||
|
|
||||||
# pevna pseudo-nahodnost
|
|
||||||
rnd = random.Random(x=42)
|
|
||||||
|
|
||||||
# users
|
|
||||||
admin = User.objects.create_superuser(username='admin', email='', password='admin')
|
|
||||||
|
|
||||||
self.stderr.write('Vytvarim pseudo-nahodna data')
|
|
||||||
|
|
||||||
orgs = []
|
|
||||||
for org in ['anet', 'bara', 'cyril', 'david', 'eva', 'filip']:
|
|
||||||
o = User.objects.create_user(username=org, password=org)
|
|
||||||
o.first_name = org.capitalize()
|
|
||||||
o.save()
|
|
||||||
orgs.append(o)
|
|
||||||
|
|
||||||
# skoly
|
|
||||||
sm.Skola.objects.create(mesto = u'Praha', stat='CZ', psc='101 00', ulice=u'Krátká 5', nazev=u'První SŠ')
|
|
||||||
sm.Skola.objects.create(mesto = u'Praha', stat='CZ', psc='102 00', ulice=u'Dlouhá 5', nazev=u'Druhá SŠ')
|
|
||||||
sm.Skola.objects.create(mesto = u'Praha', stat='CZ', psc='103 00', ulice=u'Široká 3', nazev=u'Třetí SŠ')
|
|
||||||
sm.Skola.objects.create(mesto = u'Ostrava', stat='CZ', psc='700 00', ulice=u'Hluboká 42', nazev=u'Hutní gympl')
|
|
||||||
sm.Skola.objects.create(mesto = u'Humenné', stat='SK', psc='012 34', ulice=u'Pltká 1', nazev=u'Sredná škuola')
|
|
||||||
|
|
||||||
# resitele
|
|
||||||
for i in range(20):
|
|
||||||
skola = rnd.choice(sm.Skola.objects.all())
|
|
||||||
pohlavi = rnd.randint(0,1)
|
|
||||||
sm.Resitel.objects.create(skola = skola, datum_prihlaseni = datetime.date(rnd.randint(2002, 2014), rnd.randint(1,12), 1),
|
|
||||||
jmeno = u'Řešitel' if pohlavi else u'Řešitelka', prijmeni = 'Číslo-%s' % (i), rok_maturity = rnd.randint(2015, 2019),
|
|
||||||
stat = skola.stat, zasilat = sm.Resitel.ZASILAT_NIKAM, pohlavi_muz = pohlavi)
|
|
||||||
|
|
||||||
# rocniky
|
|
||||||
for ri in range(17, 22):
|
|
||||||
r = sm.Rocnik.objects.create(prvni_rok = 1993 + ri, rocnik = ri)
|
|
||||||
|
|
||||||
# cisla
|
|
||||||
cisel = rnd.randint(4, 6)
|
|
||||||
cs = {}
|
|
||||||
for ci in range(1, cisel + 1):
|
|
||||||
vydano = datetime.date(r.prvni_rok, ci + 6, 1)
|
|
||||||
deadline = datetime.date(r.prvni_rok, ci + 8, 1) if ci + 2 < cisel else None
|
|
||||||
c = sm.Cislo.objects.create(rocnik = r, cislo = str(ci), datum_vydani=vydano, datum_deadline=deadline)
|
|
||||||
cs[ci] = c
|
|
||||||
|
|
||||||
# problemy resene v ci
|
|
||||||
seq='#ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
||||||
if ci >= 3:
|
|
||||||
for pi in range(1, 4):
|
|
||||||
p = sm.Problem.objects.create(autor = rnd.choice(orgs), cislo_zadani=cs[ci-2], cislo_reseni=cs[ci],
|
|
||||||
opravovatel = rnd.choice(orgs), kod = str(pi), nazev = u'Dummy úloha %s-%s' % (seq[ci], seq[pi]),
|
|
||||||
stav = sm.Problem.STAV_ZADANY, typ = sm.Problem.TYP_ULOHA, body = rnd.randint(1, 5))
|
|
||||||
|
|
||||||
for resi in range(rnd.randint(0, 7)):
|
|
||||||
res = sm.Reseni.objects.create(problem = p, resitel = rnd.choice(sm.Resitel.objects.all()),
|
|
||||||
body = rnd.randint(0, p.body), cislo_body = cs[ci])
|
|
||||||
|
|
||||||
nastaveni = sm.Nastaveni.objects.create(aktualni_rocnik = sm.Rocnik.objects.last(),
|
|
||||||
aktualni_cislo = sm.Cislo.objects.last())
|
|
||||||
|
|
||||||
self.stderr.write('Vytvoreno %d uzivatelu, %d skol, %d resitelu, %d rocniku, %d cisel, %d problemu, %d reseni.' %
|
|
||||||
(User.objects.count(), sm.Skola.objects.count(), sm.Resitel.objects.count(), sm.Rocnik.objects.count(),
|
|
||||||
sm.Cislo.objects.count(), sm.Problem.objects.count(), sm.Reseni.objects.count()))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,10 @@ from django.utils.encoding import force_unicode
|
||||||
from django_countries.fields import CountryField
|
from django_countries.fields import CountryField
|
||||||
from solo.models import SingletonModel
|
from solo.models import SingletonModel
|
||||||
|
|
||||||
|
from ckeditor.fields import RichTextField
|
||||||
|
from redactor.fields import RedactorField
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Mělo by být částečně vytaženo z Aesopa
|
# Mělo by být částečně vytaženo z Aesopa
|
||||||
# viz https://ovvp.mff.cuni.cz/wiki/aesop/export-skol.
|
# viz https://ovvp.mff.cuni.cz/wiki/aesop/export-skol.
|
||||||
|
@ -155,6 +159,11 @@ class Rocnik(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return force_unicode(u'%s (%d/%d)' % (self.rocnik, self.prvni_rok, self.prvni_rok+1))
|
return force_unicode(u'%s (%d/%d)' % (self.rocnik, self.prvni_rok, self.prvni_rok+1))
|
||||||
|
|
||||||
|
def roman(self):
|
||||||
|
if self.rocnik.isdigit():
|
||||||
|
return force_unicode(roman(int(self.rocnik)))
|
||||||
|
else:
|
||||||
|
return force_unicode(self.rocnik)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Cislo(models.Model):
|
class Cislo(models.Model):
|
||||||
|
@ -320,3 +329,11 @@ class Nastaveni(SingletonModel):
|
||||||
return u'Nastavení semináře'
|
return u'Nastavení semináře'
|
||||||
|
|
||||||
|
|
||||||
|
def roman(num):
|
||||||
|
ints = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
|
||||||
|
nums = ('M', 'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')
|
||||||
|
res = ""
|
||||||
|
for i, n in zip(ints, nums):
|
||||||
|
res += n * (num // i)
|
||||||
|
num %= i
|
||||||
|
return res
|
||||||
|
|
|
@ -1,3 +1,79 @@
|
||||||
from django.test import TestCase
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import random
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
import django.contrib.auth
|
||||||
|
from django.db import transaction
|
||||||
|
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni
|
||||||
|
|
||||||
|
User = django.contrib.auth.get_user_model()
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def create_test_data():
|
||||||
|
# pevna pseudo-nahodnost
|
||||||
|
rnd = random.Random(x=42)
|
||||||
|
|
||||||
|
# users
|
||||||
|
admin = User.objects.create_superuser(username='admin', email='', password='admin')
|
||||||
|
|
||||||
|
orgs = []
|
||||||
|
for org in ['anet', 'bara', 'cyril', 'david', 'eva', 'filip']:
|
||||||
|
o = User.objects.create_user(username=org, password=org)
|
||||||
|
o.first_name = org.capitalize()
|
||||||
|
o.save()
|
||||||
|
orgs.append(o)
|
||||||
|
|
||||||
|
# skoly
|
||||||
|
Skola.objects.create(mesto = u'Praha', stat='CZ', psc='101 00', ulice=u'Krátká 5', nazev=u'První SŠ')
|
||||||
|
Skola.objects.create(mesto = u'Praha', stat='CZ', psc='102 00', ulice=u'Dlouhá 5', nazev=u'Druhá SŠ')
|
||||||
|
Skola.objects.create(mesto = u'Praha', stat='CZ', psc='103 00', ulice=u'Široká 3', nazev=u'Třetí SŠ')
|
||||||
|
Skola.objects.create(mesto = u'Ostrava', stat='CZ', psc='700 00', ulice=u'Hluboká 42', nazev=u'Hutní gympl')
|
||||||
|
Skola.objects.create(mesto = u'Humenné', stat='SK', psc='012 34', ulice=u'Pltká 1', nazev=u'Sredná škuola')
|
||||||
|
|
||||||
|
# resitele
|
||||||
|
for i in range(20):
|
||||||
|
skola = rnd.choice(Skola.objects.all())
|
||||||
|
pohlavi = rnd.randint(0,1)
|
||||||
|
Resitel.objects.create(skola = skola, datum_prihlaseni = datetime.date(rnd.randint(2002, 2014), rnd.randint(1,12), 1),
|
||||||
|
jmeno = u'Řešitel' if pohlavi else u'Řešitelka', prijmeni = 'Číslo-%s' % (i), rok_maturity = rnd.randint(2015, 2019),
|
||||||
|
stat = skola.stat, zasilat = Resitel.ZASILAT_NIKAM, pohlavi_muz = pohlavi)
|
||||||
|
|
||||||
|
# rocniky
|
||||||
|
for ri in range(17, 22):
|
||||||
|
r = Rocnik.objects.create(prvni_rok = 1993 + ri, rocnik = ri)
|
||||||
|
|
||||||
|
# cisla
|
||||||
|
cisel = rnd.randint(4, 6)
|
||||||
|
cs = {}
|
||||||
|
for ci in range(1, cisel + 1):
|
||||||
|
vydano = datetime.date(r.prvni_rok, ci + 6, 1)
|
||||||
|
deadline = datetime.date(r.prvni_rok, ci + 8, 1) if ci + 2 < cisel else None
|
||||||
|
c = Cislo.objects.create(rocnik = r, cislo = str(ci), datum_vydani=vydano, datum_deadline=deadline)
|
||||||
|
cs[ci] = c
|
||||||
|
|
||||||
|
# problemy resene v ci
|
||||||
|
seq='#ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||||
|
if ci >= 3:
|
||||||
|
for pi in range(1, 4):
|
||||||
|
p = Problem.objects.create(autor = rnd.choice(orgs), cislo_zadani=cs[ci-2], cislo_reseni=cs[ci],
|
||||||
|
opravovatel = rnd.choice(orgs), kod = str(pi), nazev = u'Dummy úloha %s-%s' % (seq[ci], seq[pi]),
|
||||||
|
stav = Problem.STAV_ZADANY, typ = Problem.TYP_ULOHA, body = rnd.randint(1, 5))
|
||||||
|
|
||||||
|
for resi in range(rnd.randint(0, 7)):
|
||||||
|
res = Reseni.objects.create(problem = p, resitel = rnd.choice(Resitel.objects.all()),
|
||||||
|
body = rnd.randint(0, p.body), cislo_body = cs[ci])
|
||||||
|
|
||||||
|
nastaveni = Nastaveni.objects.create(aktualni_rocnik = Rocnik.objects.last(),
|
||||||
|
aktualni_cislo = Cislo.objects.last())
|
||||||
|
|
||||||
|
|
||||||
|
class SeminarTests(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
create_test_data()
|
||||||
|
|
||||||
|
def test_rocniky(self):
|
||||||
|
r19 = Rocnik.objects.get(rocnik=19)
|
||||||
|
self.assertEqual(r19.roman(), 'XIX')
|
||||||
|
|
||||||
# Create your tests here.
|
|
||||||
|
|
Loading…
Reference in a new issue