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', | ||||
|     'django_countries', | ||||
|     'solo', | ||||
|     'ckeditor', | ||||
| 
 | ||||
|     # 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 | ||||
| 
 | ||||
| SEMINAR_RESENI_DIR = os.path.join(BASE_DIR, 'media', 'reseni') | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ from django.conf import settings | |||
| urlpatterns = i18n_patterns('', | ||||
| 
 | ||||
|     url(r'^admin/', include(admin.site.urls)),  # NOQA | ||||
|     url(r'^ckeditor/', include('ckeditor.urls')), | ||||
|     url(r'^', include('seminar.urls')), | ||||
| ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ django-reversion==1.8.5 | |||
| django-sekizai==0.8.1 | ||||
| django-countries==3.2 | ||||
| django-solo==1.1.0 | ||||
| django-ckeditor==4.4.7 | ||||
| 
 | ||||
| # debug tools/extensions | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,10 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| 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 ckeditor.widgets import CKEditorWidget | ||||
| 
 | ||||
| from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni | ||||
| 
 | ||||
| ### Nastaveni | ||||
| 
 | ||||
|  | @ -106,7 +109,15 @@ class ReseniInline(admin.StackedInline): | |||
| 
 | ||||
| ### 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): | ||||
|     form = ProblemAdminForm | ||||
| #    readonly_fields = ['autor'] | ||||
|     fieldsets = [ | ||||
|         (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.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): | ||||
|     help = "Clear database and load testing data." | ||||
| 
 | ||||
|  | @ -18,76 +24,13 @@ class Command(NoArgsCommand): | |||
|             os.rename(dbfile, dbfile + '.old') | ||||
|             self.stderr.write('Stara databaze prejmenovana na "%s"' % (dbfile + '.old')) | ||||
|         call_command('migrate', noinput=True) | ||||
|         self.load_testing_data() | ||||
| 
 | ||||
|     def load_testing_data(self): | ||||
|         from seminar import models as sm | ||||
|         import django.contrib.auth | ||||
|         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())) | ||||
|         self.stdout.write('Vytvarim uzivatele "admin" (heslo "admin") a pseudo-nahodna data ...') | ||||
|         create_test_data() | ||||
|         self.stdout.write('Vytvoreno %d uzivatelu, %d skol, %d resitelu, %d rocniku, %d cisel, %d problemu, %d reseni.' % | ||||
|                 (User.objects.count(), Skola.objects.count(), Resitel.objects.count(), Rocnik.objects.count(), | ||||
|                 Cislo.objects.count(), Problem.objects.count(), Reseni.objects.count())) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -13,6 +13,10 @@ from django.utils.encoding import force_unicode | |||
| from django_countries.fields import CountryField | ||||
| 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 | ||||
| # viz https://ovvp.mff.cuni.cz/wiki/aesop/export-skol. | ||||
|  | @ -155,6 +159,11 @@ class Rocnik(models.Model): | |||
|     def __str__(self): | ||||
|         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 | ||||
| class Cislo(models.Model): | ||||
|  | @ -320,3 +329,11 @@ class Nastaveni(SingletonModel): | |||
|         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
	
	 Tomas Gavenciak
						Tomas Gavenciak