Merge branch 'Galerie'
This commit is contained in:
		
						commit
						ef5470bcb6
					
				
					 23 changed files with 807 additions and 6 deletions
				
			
		
							
								
								
									
										24
									
								
								galerie/TODO
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								galerie/TODO
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| ======== | ||||
| | TODO | | ||||
| |======| | ||||
| 
 | ||||
| Aktualni | ||||
| * do CSS | ||||
|   * nahledy | ||||
|     * nastylovat tabulku s nahledy | ||||
|     * komentare uz na nahledy? | ||||
|   * detail | ||||
|     * nahledy pred a po | ||||
|     * opravit prechodove sipky | ||||
|     * vyrobit prechodove sipky ve M&M-stylu | ||||
| 
 | ||||
| Dlouhodobe | ||||
| * sipky na prechazeni mezi fotkami | ||||
| * hromadne PRIDANI fotek do jiz existujici galerie | ||||
| 
 | ||||
| Fylozoficke | ||||
| * zvolit velikosti velke a male fotky | ||||
| * je potreba i jine razeni nez automaticky podle casu nebo staci podgalerie? | ||||
|   * napr. dve hry na dvou ruznych mistech ve stejny cas | ||||
|   * fotky od ucastniku ze hry (skupinky se pohybuji ve stejny cas, ale maji sled fotek) -- nestaci to pripadne vrazit do podgalerii? | ||||
| 
 | ||||
							
								
								
									
										0
									
								
								galerie/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								galerie/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										43
									
								
								galerie/admin.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								galerie/admin.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| #coding: utf-8 | ||||
| 
 | ||||
| from galerie.models import Obrazek, Galerie | ||||
| from django.contrib import admin | ||||
| from django.http import HttpResponseRedirect | ||||
| 
 | ||||
| # akction | ||||
| 
 | ||||
| def zverejnit_fotogalerii(modeladmin, request, queryset): | ||||
|     '''zverejni vybranou fotogalerii i jeji vsechny podgalerie''' | ||||
|     for galerie in queryset: | ||||
|         galerie.zobrazit = 0 | ||||
|         galerie.save() | ||||
|         zverejnit_fotogalerii(modeladmin, request, | ||||
|                 Galerie.objects.filter(galerie_up = galerie)) | ||||
|     zverejnit_fotogalerii.short_description = 'Zveřejnit fotogalerie' | ||||
| 
 | ||||
| 
 | ||||
| def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset): | ||||
|     '''zneverjni vybranou fotogalerii i jeji vsechny podgalerie''' | ||||
|     for galerie in queryset: | ||||
|         galerie.zobrazit = 1 | ||||
|         galerie.save() | ||||
|         prepnout_fotogalerii_do_org_rezimu(modeladmin, request, | ||||
|                 Galerie.objects.filter(galerie_up = galerie)) | ||||
|     prepnout_fotogalerii_do_org_rezimu.short_description = \ | ||||
|             'Přepnout do režimu úprav (zneveřejní galerii)' | ||||
| 
 | ||||
| class GalerieInline(admin.TabularInline): | ||||
|   model = Obrazek | ||||
| 
 | ||||
| class ObrazekAdmin(admin.ModelAdmin): | ||||
|   list_display = ('obrazek_velky', 'nazev', 'popis') | ||||
|    | ||||
| class GalerieAdmin(admin.ModelAdmin):  | ||||
|   model = Galerie | ||||
|   fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni') | ||||
|   list_display = ('nazev', 'pk', 'datum_zmeny', 'zobrazit', 'soustredeni') | ||||
|   inlines = [GalerieInline] | ||||
|   actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu] | ||||
| 
 | ||||
| admin.site.register(Obrazek, ObrazekAdmin) | ||||
| admin.site.register(Galerie, GalerieAdmin) | ||||
							
								
								
									
										11
									
								
								galerie/forms.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								galerie/forms.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| #coding: utf-8 | ||||
| 
 | ||||
| from django import forms | ||||
| from seminar.models import Soustredeni | ||||
| 
 | ||||
| class KomentarForm(forms.Form): | ||||
|     komentar = forms.CharField(label = "Komentář:", max_length = 300, required=False) | ||||
| 
 | ||||
| class NewGalerieForm(forms.Form): | ||||
|     nazev = forms.CharField(label = "Název galerie", max_length = 100) | ||||
|     popis = forms.CharField(label = "Popis", required = False, max_length = 2000, widget = forms.Textarea) | ||||
							
								
								
									
										59
									
								
								galerie/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								galerie/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| import django.db.models.deletion | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0033_organizator_studuje_popisek'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.CreateModel( | ||||
|             name='Galerie', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | ||||
|                 ('nazev', models.CharField(max_length=100, verbose_name=b'N\xc3\xa1zev')), | ||||
|                 ('datum_vytvoreni', models.DateTimeField(auto_now_add=True, verbose_name=b'Datum vytvo\xc5\x99en\xc3\xad')), | ||||
|                 ('datum_zmeny', models.DateTimeField(auto_now=True, verbose_name=b'Datum posledn\xc3\xad zm\xc4\x9bny')), | ||||
|                 ('popis', models.TextField(null=True, verbose_name=b'Popis', blank=True)), | ||||
|                 ('zobrazit', models.IntegerField(default=1, verbose_name=b'Zobrazit?', choices=[(0, b'V\xc5\xbedy'), (1, b'Organiz\xc3\xa1tor\xc5\xafm'), (2, b'Nikdy')])), | ||||
|                 ('galerie_up', models.ForeignKey(blank=True, to='galerie.Galerie', null=True)), | ||||
|                 ('soustredeni', models.ForeignKey(blank=True, to='seminar.Soustredeni', null=True)), | ||||
|             ], | ||||
|             options={ | ||||
|                 'verbose_name': 'Galerie', | ||||
|                 'verbose_name_plural': 'Galerie', | ||||
|             }, | ||||
|             bases=(models.Model,), | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name='Obrazek', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | ||||
|                 ('obrazek_velky', models.ImageField(help_text=b'Lze vlo\xc5\xbeit libovoln\xc4\x9b velk\xc3\xbd obr\xc3\xa1zek. Ide\xc3\xa1ln\xc3\xad je, aby alespo\xc5\x88 jeden rozm\xc4\x9br m\xc4\x9bl alespo\xc5\x88 500px.', upload_to=b'Galerie/%Y/%m/%d')), | ||||
|                 ('obrazek_stredni', models.ImageField(upload_to=b'Galerie/%Y/%m/%d/stredni', null=True, editable=False)), | ||||
|                 ('obrazek_maly', models.ImageField(upload_to=b'Galerie/%Y/%m/%d/male', null=True, editable=False)), | ||||
|                 ('nazev', models.CharField(max_length=50, null=True, verbose_name=b'N\xc3\xa1zev', blank=True)), | ||||
|                 ('popis', models.TextField(null=True, verbose_name=b'Popis', blank=True)), | ||||
|                 ('datum_vlozeni', models.DateTimeField(auto_now_add=True, verbose_name=b'Datum vlo\xc5\xbeen\xc3\xad')), | ||||
|                 ('datum', models.DateTimeField(verbose_name=b'Datum po\xc5\x99\xc3\xadzen\xc3\xad fotografie')), | ||||
|                 ('poradi', models.IntegerField(null=True, verbose_name=b'Po\xc5\x99ad\xc3\xad', blank=True)), | ||||
|                 ('galerie', models.ForeignKey(to='galerie.Galerie')), | ||||
|             ], | ||||
|             options={ | ||||
|                 'verbose_name': 'Obr\xe1zek', | ||||
|                 'verbose_name_plural': 'Obr\xe1zky', | ||||
|             }, | ||||
|             bases=(models.Model,), | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name='galerie', | ||||
|             name='titulni_obrazek', | ||||
|             field=models.ForeignKey(related_name='+', on_delete=django.db.models.deletion.SET_NULL, to='galerie.Obrazek', null=True), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										27
									
								
								galerie/migrations/0002_auto_20151013_1145.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								galerie/migrations/0002_auto_20151013_1145.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| import django.db.models.deletion | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('galerie', '0001_initial'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterField( | ||||
|             model_name='galerie', | ||||
|             name='titulni_obrazek', | ||||
|             field=models.ForeignKey(related_name='+', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='galerie.Obrazek', null=True), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='obrazek', | ||||
|             name='datum', | ||||
|             field=models.DateTimeField(null=True, verbose_name=b'Datum po\xc5\x99\xc3\xadzen\xc3\xad fotografie', blank=True), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										39
									
								
								galerie/migrations/0003_add_galerie_poradi.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								galerie/migrations/0003_add_galerie_poradi.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| import galerie.models | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('galerie', '0002_auto_20151013_1145'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AddField( | ||||
|             model_name='galerie', | ||||
|             name='poradi', | ||||
|             field=models.IntegerField(null=True, verbose_name=b'Po\xc5\x99ad\xc3\xad', blank=True), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='obrazek', | ||||
|             name='obrazek_maly', | ||||
|             field=models.ImageField(upload_to=galerie.models.obrazek_filename_maly, null=True, editable=False), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='obrazek', | ||||
|             name='obrazek_stredni', | ||||
|             field=models.ImageField(upload_to=galerie.models.obrazek_filename_stredni, null=True, editable=False), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='obrazek', | ||||
|             name='obrazek_velky', | ||||
|             field=models.ImageField(help_text=b'Lze vlo\xc5\xbeit libovoln\xc4\x9b velk\xc3\xbd obr\xc3\xa1zek. Ide\xc3\xa1ln\xc3\xad je, aby alespo\xc5\x88 jeden rozm\xc4\x9br m\xc4\x9bl alespo\xc5\x88 500px.', upload_to=galerie.models.obrazek_filename), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										0
									
								
								galerie/migrations/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								galerie/migrations/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										178
									
								
								galerie/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								galerie/models.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,178 @@ | |||
| # coding: utf-8 | ||||
| 
 | ||||
| from django.db import models | ||||
| import seminar.models | ||||
| from django.db.models import Q | ||||
| from django.utils import timezone | ||||
| from django.utils.encoding import force_unicode | ||||
| 
 | ||||
| from PIL import Image | ||||
| from PIL.ExifTags import TAGS | ||||
| import os | ||||
| from cStringIO import StringIO | ||||
| from django.core.files.base import ContentFile | ||||
| from datetime import datetime | ||||
| 
 | ||||
| from seminar.models import Soustredeni | ||||
| 
 | ||||
| VZDY=0 | ||||
| ORG=1 | ||||
| NIKDY=2 | ||||
| VIDITELNOST = ( | ||||
|     (VZDY, 'Vždy'), | ||||
|     (ORG, 'Organizátorům'), | ||||
|     (NIKDY, 'Nikdy'), | ||||
| ) | ||||
| 
 | ||||
| def get_exif(fn): | ||||
|     ret = {} | ||||
|     info = fn._getexif() | ||||
|     for tag, value in info.items(): | ||||
|         decoded = TAGS.get(tag, tag) | ||||
|         ret[decoded] = value | ||||
|     return ret | ||||
| 
 | ||||
| def flip_horizontal(im): return im.transpose(Image.FLIP_LEFT_RIGHT) | ||||
| def flip_vertical(im): return im.transpose(Image.FLIP_TOP_BOTTOM) | ||||
| def rotate_180(im): return im.transpose(Image.ROTATE_180) | ||||
| def rotate_90(im): return im.transpose(Image.ROTATE_90) | ||||
| def rotate_270(im): return im.transpose(Image.ROTATE_270) | ||||
| def transpose(im): return rotate_90(flip_horizontal(im)) | ||||
| def transverse(im): return rotate_90(flip_vertical(im)) | ||||
| orientation_funcs = [None, | ||||
|                  lambda x: x, | ||||
|                  flip_horizontal, | ||||
|                  rotate_180, | ||||
|                  flip_vertical, | ||||
|                  transpose, | ||||
|                  rotate_270, | ||||
|                  transverse, | ||||
|                  rotate_90 | ||||
|                 ] | ||||
| 
 | ||||
| 
 | ||||
| def obrazek_filename(self, filename): | ||||
|     return obrazek_filename_obecny(self, filename, "velky") | ||||
| 
 | ||||
| def obrazek_filename_stredni(self, filename): | ||||
|     return obrazek_filename_obecny(self, filename, "stredni") | ||||
| 
 | ||||
| def obrazek_filename_maly(self, filename): | ||||
|     return obrazek_filename_obecny(self, filename, "maly") | ||||
| 
 | ||||
| def obrazek_filename_obecny(self, filename, typ): | ||||
|     gal = self.galerie | ||||
|     cesta = "" | ||||
|     while(not gal.soustredeni): | ||||
|         cesta = os.path.join(force_unicode(gal.nazev), cesta) | ||||
|         gal = gal.galerie_up | ||||
|     return os.path.join('Galerie', force_unicode(gal.soustredeni), cesta, typ, force_unicode(self.nazev)) | ||||
| 
 | ||||
| class Obrazek(models.Model): | ||||
|   obrazek_velky = models.ImageField(upload_to=obrazek_filename, | ||||
|     help_text = "Lze vložit libovolně velký obrázek. Ideální je, aby alespoň jeden rozměr měl alespoň 500px.") | ||||
|   obrazek_stredni = models.ImageField(upload_to=obrazek_filename_stredni, null = True, editable = False) | ||||
|   obrazek_maly = models.ImageField(upload_to=obrazek_filename_maly, null = True, editable = False) | ||||
|   nazev = models.CharField('Název', max_length=50, blank = True, null = True) | ||||
|   popis = models.TextField('Popis', blank = True, null = True) | ||||
|   datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add = True) | ||||
|   datum = models.DateTimeField('Datum pořízení fotografie', blank = True, null = True) | ||||
|   galerie = models.ForeignKey('Galerie') | ||||
|   poradi = models.IntegerField('Pořadí', blank = True, null = True) | ||||
|   def __unicode__(self): | ||||
|     return self.nazev + " -- " + unicode(self.obrazek_velky.name) + " (" + str(self.datum) + ")" | ||||
|   class Meta: | ||||
|     verbose_name = 'Obrázek' | ||||
|     verbose_name_plural = 'Obrázky' | ||||
|   def save(self): | ||||
|     original = Image.open(self.obrazek_velky) | ||||
|     # vycteni EXIFu | ||||
|     exif = get_exif(original) | ||||
|     if exif['Orientation']: | ||||
|         f = orientation_funcs[exif['Orientation']] | ||||
|         original_otoceny = f(original) | ||||
|         original_otoceny.format = original.format | ||||
|         original = original_otoceny | ||||
|     # datum podle EXIfu | ||||
|     if exif['DateTimeOriginal']: | ||||
|         datum_string = ":".join(exif['DateTimeOriginal'].split(' ')).split(":") | ||||
|         datum_int = [] | ||||
|         for retezec in datum_string: | ||||
|             datum_int.append(int(retezec)) | ||||
|         self.datum = datetime(datum_int[0], datum_int[1], datum_int[2], | ||||
|                               datum_int[3], datum_int[4], datum_int[5]) | ||||
|     jmeno = os.path.basename(self.obrazek_velky.file.name) | ||||
|     if not self.obrazek_stredni: | ||||
|       Obrazek._vyrobMiniaturu(original, jmeno, 500, self.obrazek_stredni) | ||||
|     if not self.obrazek_maly: | ||||
|       Obrazek._vyrobMiniaturu(original, jmeno, 200, self.obrazek_maly) | ||||
|     super(Obrazek, self).save() | ||||
| 
 | ||||
|   @staticmethod | ||||
|   def _vyrobMiniaturu(original, jmeno, maximum, field): | ||||
|     zmensenina = Obrazek._zmensiObrazek(original, maximum) | ||||
|     f = StringIO() | ||||
|     try: | ||||
|       zmensenina.save(f, format=original.format) | ||||
|       data = ContentFile(f.getvalue()) | ||||
|     finally: | ||||
|       f.close() | ||||
|     field.save(jmeno, data, save = False) | ||||
|    | ||||
|   @staticmethod | ||||
|   def _zmensiObrazek(original, maximum): | ||||
|     """Preskaluje obrazek tak, aby byl zachovan pomer stran a zadny rozmer | ||||
|     nepresahoval maxRozmer. Pokud zadny rozmer nepresahuje maxRozmer, tak | ||||
|     vrati puvodni obrazek (tj. nedojde ke zvetseni obrazku).""" | ||||
|     novaVelikost = Obrazek._zmensiVelikost(original.size, maximum) | ||||
|     return original.resize(novaVelikost, Image.ANTIALIAS) | ||||
| 
 | ||||
|   @staticmethod | ||||
|   def _zmensiVelikost(velikost, maximum): | ||||
|     maximum = float(maximum) | ||||
|     w, h = velikost | ||||
|     soucasneMaximum = max(w, h) | ||||
|     if soucasneMaximum <= maximum: | ||||
|       return velikost | ||||
|     pomer = maximum/soucasneMaximum | ||||
|     return (int(w * pomer), int(h * pomer)) | ||||
|    | ||||
| 
 | ||||
| class Galerie(models.Model): | ||||
|   nazev = models.CharField('Název', max_length=100) | ||||
|   datum_vytvoreni = models.DateTimeField('Datum vytvoření', auto_now_add = True) | ||||
|   datum_zmeny = models.DateTimeField('Datum poslední změny', auto_now = True) | ||||
|   popis = models.TextField('Popis', blank = True, null = True) | ||||
|   titulni_obrazek = models.ForeignKey(Obrazek, blank = True, null = True, related_name = "+", on_delete = models.SET_NULL) | ||||
|   zobrazit = models.IntegerField('Zobrazit?', default = ORG, choices = VIDITELNOST) | ||||
|   galerie_up = models.ForeignKey('Galerie', blank = True, null = True) | ||||
|   soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True) | ||||
|   poradi = models.IntegerField('Pořadí', blank = True, null = True) | ||||
| 
 | ||||
|   def __unicode__(self): | ||||
|     return self.nazev | ||||
|   class Meta: | ||||
|     verbose_name = 'Galerie' | ||||
|     verbose_name_plural = 'Galerie' | ||||
| 
 | ||||
|   #def link_na_preview(self): | ||||
|     #"""Odkaz na galerii, používá se v admin rozhranní. """ | ||||
|     #return '<a href="/fotogalerie/galerie/%s/">Preview</a>' % self.id | ||||
|   #link_na_preview.allow_tags = True | ||||
|   #link_na_preview.short_description = 'Zobrazit galerii' | ||||
| # | ||||
|   #def je_publikovano(self): | ||||
|     #"""Vraci True, pokud je tato galerie publikovana. """  | ||||
|     #if self.zobrazit == VZDY: | ||||
|       #return True | ||||
|     #if self.zobrazit == PODLE_CLANKU: | ||||
|       #for clanek in self.clanek_set.all(): | ||||
|         #if clanek.je_publikovano(): | ||||
|           #return True | ||||
|     #return False | ||||
| # | ||||
|   #@staticmethod | ||||
|   #def publikovane_galerie(): | ||||
|     #"""Vraci galerie, ktere uz maji byt publikovane.""" | ||||
|     #clanky = Blog.models.Clanek.publikovane_clanky() | ||||
|     #return Galerie.objects.filter(Q(zobrazit=VZDY) | (Q(clanek__in=clanky) & Q(zobrazit=PODLE_CLANKU))).distinct() | ||||
							
								
								
									
										2
									
								
								galerie/static/galerie/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								galerie/static/galerie/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | |||
| images | ||||
| lightbox | ||||
							
								
								
									
										
											BIN
										
									
								
								galerie/static/galerie/prvky/dalsi.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								galerie/static/galerie/prvky/dalsi.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										
											BIN
										
									
								
								galerie/static/galerie/prvky/predchozi.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								galerie/static/galerie/prvky/predchozi.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										6
									
								
								galerie/templates/galerie/Base.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								galerie/templates/galerie/Base.html
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| {% extends "base.html" %} | ||||
| 
 | ||||
| {# TODO predelat pres context processor #} | ||||
| {% block header %}soustredeni{% endblock %} | ||||
| {% block menu_soustredeni %}selected{% endblock %} | ||||
| {% block submenu %}{% include 'seminar/soustredeni/submenu.html' %}{% endblock %} | ||||
							
								
								
									
										62
									
								
								galerie/templates/galerie/Galerie.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								galerie/templates/galerie/Galerie.html
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,62 @@ | |||
| {% extends "galerie/Base.html" %} | ||||
| 
 | ||||
| {% block title %}{% block nadpis1a %} | ||||
| {{galerie.nazev}} | Galerie | ||||
| {% endblock %}{% endblock %} | ||||
| 
 | ||||
| {% block content %} | ||||
|   <h1><a title="Zpět na náhled fotek" href="../#obsah">{{galerie.nazev}}</a></h1> | ||||
|   <div class="galerie_top" id="obsah"> | ||||
|     {% for obrazek in obrazky_predchozi %} | ||||
|     <a href="../{{obrazek.pk}}#obsah"><img src="{{obrazek.obrazek_maly.url}}" height="100"></a> | ||||
|     {% endfor %} | ||||
|   </div> | ||||
| 
 | ||||
| 
 | ||||
|   {# TODO šipky na přecházeni dodelat ve stylech #} | ||||
|   <div class="galerie"> | ||||
|     {% if obrazky_predchozi %} | ||||
|       {% with obrazky_predchozi|last as predchozi_obrazek %} | ||||
|         <div> | ||||
|           <a title="Předchozí" class="predchozi_obrazek" href="../{{predchozi_obrazek.pk}}#obsah"></a> | ||||
|         </div> | ||||
|       {% endwith %} | ||||
|     {% endif%} | ||||
|     <img src={{obrazek.obrazek_stredni.url}} | ||||
|          height="{{vyska}}" | ||||
|          width="{{sirka}}" | ||||
|          alt="{{obrazek.popis}}" | ||||
|          class="obrazek"> | ||||
|     {% if obrazky_dalsi %} | ||||
|       {% with obrazky_dalsi|first as dalsi_obrazek %} | ||||
|         <div> | ||||
|           <a title="Další" class="dalsi_obrazek" href="../{{dalsi_obrazek.pk}}#obsah"></a> | ||||
|         </div> | ||||
|       {% endwith %} | ||||
|     {% endif%} | ||||
|   </div> | ||||
| 
 | ||||
|   {# Popisek fotky #} | ||||
|   <div class="popis"> | ||||
|     {% if preview %} | ||||
|     <form action=".#obsah" method="post"> | ||||
|       {% csrf_token %} | ||||
|       <table> | ||||
|         <tr><td><label>Aktuální komentář:</label></td><td>{{obrazek.popis}}</td> | ||||
|         {{form.as_table}} | ||||
|         <tr><td></td><td><input name="odeslat" type="submit" value="Změň komentář"></td></tr> | ||||
|       </table> | ||||
|     </form> | ||||
|     {% else %} | ||||
|       {% if obrazek.popis %} | ||||
|         {{obrazek.popis}} | ||||
|       {% endif %} | ||||
|     {% endif %} | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="galerie_bot"> | ||||
|     {% for obrazek in obrazky_dalsi %} | ||||
|     <a href="../{{obrazek.pk}}#obsah"><img src="{{obrazek.obrazek_maly.url}}" height="100"></a> | ||||
|     {% endfor %} | ||||
|   </div> | ||||
| {% endblock %} | ||||
							
								
								
									
										77
									
								
								galerie/templates/galerie/GalerieNahled.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								galerie/templates/galerie/GalerieNahled.html
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,77 @@ | |||
| {% extends "galerie/Base.html" %} | ||||
| 
 | ||||
| {% block title %}{% block nadpis1a %} | ||||
| {{galerie.nazev}} | Galerie TODO title | ||||
| {% endblock %}{% endblock %} | ||||
| 
 | ||||
| {% block content %} | ||||
|   <h2>{{galerie.nazev}}</h2> | ||||
| 
 | ||||
|   {# podgalerie #} | ||||
|   {% if podgalerie or galerie.galerie_up %} | ||||
|     <h3> PODGALERIE </h3> | ||||
|     <ul> | ||||
|     {% if galerie.galerie_up %} | ||||
|       <li><a href="../{{galerie.galerie_up.pk}}">..</a> | ||||
|     {% endif %} | ||||
|     {% for galerie in podgalerie %} | ||||
|       {% if galerie.zobrazit < 1 or user.is_staff %} | ||||
|       <li><a href="../{{galerie.pk}}">{{galerie}}</a> | ||||
|         {% if user.is_staff and galerie.zobrazit > 0 %} | ||||
|           ({{galerie.poradi}}) | ||||
|           <span class="plus"><a href="plus/{{galerie.pk}}/">+</a></span> | ||||
|           <span class="minus"><a href="minus/{{galerie.pk}}/">-</a></span> | ||||
|         {% endif %} | ||||
|       {% endif %} | ||||
|     {% endfor %} | ||||
|   </ul> | ||||
|   {% endif %} | ||||
|   {% if user.is_staff and galerie.zobrazit > 0 %} | ||||
|   <ul> | ||||
|     <li><a href="./new">VYTVOŘIT NOVOU PODGALERII </a> | ||||
|   </ul> | ||||
|   {% endif %} | ||||
| 
 | ||||
|   {# obrazky v galerii #} | ||||
|   {% if obrazky %} | ||||
|   <table class="galerie_nahled"> | ||||
|     {% for obrazek in obrazky %} | ||||
|       {% if forloop.counter|add:-1|divisibleby:3 %} | ||||
|         <tr> | ||||
|       {% endif %} | ||||
|         <td class="vystredeno"> | ||||
|           <a title="Zobrazit tuto fotografii" href="./{{obrazek.pk}}#obsah" | ||||
|             class="jednoducha-galerie"> | ||||
|           <img | ||||
|             src="{{obrazek.obrazek_maly.url}}" | ||||
|             width={% widthratio obrazek.obrazek_maly.width 200 167 %} | ||||
|             height={% widthratio obrazek.obrazek_maly.height 200 167 %} /> | ||||
|           </a> | ||||
|           <!--<a href="{{obrazek.obrazek_velky.url}}" | ||||
|             class="javascript-galerie" data-lightbox="galerie" data-title="{{obrazek.popis}}" | ||||
|             style="display: none;"> | ||||
|           <img | ||||
|             src="{{obrazek.obrazek_maly.url}}" | ||||
|             width={% widthratio obrazek.obrazek_maly.width 200 167 %} | ||||
|             height={% widthratio obrazek.obrazek_maly.height 200 167 %} /> | ||||
|           </a>--> | ||||
| 	</td> | ||||
|       {% if forloop.last %} | ||||
|         {% if not forloop.counter|divisibleby:3 %} | ||||
|           <td></td> | ||||
|         {% endif %} | ||||
|         {% if not forloop.counter|divisibleby:2 %} | ||||
|           <td></td> | ||||
|         {% endif %} | ||||
|       {% endif %} | ||||
|       {% if forloop.counter|divisibleby:3 or forloop.last %} | ||||
|         </tr> | ||||
|       {% endif %} | ||||
|     {% endfor %} | ||||
|   </table> | ||||
|   {% else %} | ||||
|     <div class="zadne-vysledky"> | ||||
|       V galerii nejsou žádné fotky. | ||||
|     </div> | ||||
|   {% endif %} | ||||
| {% endblock content %} | ||||
							
								
								
									
										22
									
								
								galerie/templates/galerie/GalerieNew.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								galerie/templates/galerie/GalerieNew.html
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| {% extends "galerie/Base.html" %} | ||||
| 
 | ||||
| {% block title %}{% block nadpis1a %} | ||||
| Vytvářím novou galerii | ||||
| {% endblock %}{% endblock %} | ||||
| 
 | ||||
| {% block content %} | ||||
| 
 | ||||
| <h2> Vytváření nové galerie </h2> | ||||
| 
 | ||||
| <h3> Vytvářím galerii k soustředění {{soustredeni}} jako {{galerie_text}}</h3> | ||||
| 
 | ||||
| <form enctype="multipart/form-data" action="." method="post"> | ||||
|   {% csrf_token %} | ||||
|   <table>{{form.as_table}} | ||||
|     <tr><td><label>Obrázky:</label></td><td><input name="obr" type="file" multiple></td></tr> | ||||
|     <tr><td> </td></tr> | ||||
|     <tr><td></td><td><input name="odeslat" type="submit" value="Vytvoř galerii"></td></tr> | ||||
|   </table> | ||||
| </form> | ||||
| 
 | ||||
| {% endblock %} | ||||
							
								
								
									
										12
									
								
								galerie/urls.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								galerie/urls.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | |||
| # coding: utf-8 | ||||
| 
 | ||||
| from django.conf.urls import patterns, include, url | ||||
| 
 | ||||
| urlpatterns = patterns('', | ||||
|    (r'^(?P<pk>\d+)/$', 'galerie.views.nahled'), | ||||
|    (r'^(?P<pk>\d+)/(?P<fotka>\d+)/$', 'galerie.views.detail'), | ||||
|    (r'^(?P<galerie>\d+)/new/$', 'galerie.views.new_galerie'), | ||||
|    (r'^(?P<galerie>\d+)/plus/(?P<subgalerie>\d+)/$', 'galerie.views.plus_galerie'), | ||||
|    (r'^(?P<galerie>\d+)/minus/(?P<subgalerie>\d+)/$', 'galerie.views.minus_galerie'), | ||||
| ) | ||||
| 
 | ||||
							
								
								
									
										168
									
								
								galerie/views.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								galerie/views.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,168 @@ | |||
| # coding: utf-8 | ||||
| 
 | ||||
| import random | ||||
| 
 | ||||
| from django.http import HttpResponse, Http404 | ||||
| from django.shortcuts import render, HttpResponseRedirect, get_object_or_404 | ||||
| from django.template import RequestContext | ||||
| from datetime import datetime | ||||
| 
 | ||||
| from galerie.models import Obrazek, Galerie | ||||
| from seminar.models import Soustredeni | ||||
| from galerie.forms import KomentarForm, NewGalerieForm | ||||
| 
 | ||||
| def zobrazit(galerie, request): | ||||
|     preview = False | ||||
|     if galerie.zobrazit >= 1: | ||||
|         if request.user.is_staff: | ||||
|             preview = True; | ||||
|         else: | ||||
|             raise Http404 | ||||
|     return preview | ||||
| 
 | ||||
| def nahled(request, pk, soustredeni): | ||||
|   """Zobrazeni nahledu vsech fotek ve skupine.""" | ||||
|   galerie = get_object_or_404(Galerie, pk=pk) | ||||
|   podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi') | ||||
|   obrazky = Obrazek.objects.filter(galerie = galerie).order_by('datum') | ||||
|   preview = zobrazit(galerie, request) | ||||
|   return render(request, 'galerie/GalerieNahled.html', | ||||
|       {'galerie' : galerie, | ||||
|        'podgalerie' : podgalerie, | ||||
|        'obrazky' : obrazky, | ||||
|        'preview' : preview, | ||||
|       }) | ||||
| 
 | ||||
| def detail(request, pk, fotka, soustredeni): | ||||
|   """Zobrazeni nahledu fotky s id 'fotka'.""" | ||||
|   MAX_VYSKA = 600 | ||||
|   MAX_SIRKA = 600 | ||||
|   MAX_VYSKA_MALA = 100 | ||||
|   MAX_SIRKA_MALA = 200 | ||||
|   NAHLEDU = 1 | ||||
| 
 | ||||
|   galerie = get_object_or_404(Galerie, pk=pk) | ||||
|   preview = zobrazit(galerie, request) | ||||
|   obrazek = get_object_or_404(Obrazek, pk=fotka) | ||||
|   obrazky = galerie.obrazek_set.all().order_by('datum') | ||||
| 
 | ||||
|   # vytvoreni a obslouzeni formulare | ||||
|   if request.method == 'POST': | ||||
|       form = KomentarForm(request.POST) | ||||
|       if form.is_valid(): | ||||
|           obrazek.popis = form.cleaned_data['komentar'] | ||||
|           obrazek.save() | ||||
|   else: | ||||
|       form = KomentarForm({'komentar': obrazek.popis}) | ||||
| 
 | ||||
|   # Poradi aktualniho obrazku v galerii/stitku. | ||||
|   for i in range(len(obrazky)): | ||||
|     if obrazky[i] == obrazek: | ||||
|       znacka = i | ||||
|       break | ||||
|   else: | ||||
|     # Obrazek neni v galerii/stitku. | ||||
|     raise Http404 | ||||
| 
 | ||||
|   # Nacteni okolnich obrazku. | ||||
|   obrazky_dalsi = obrazky[znacka+1:znacka+NAHLEDU+1] | ||||
|   if znacka > NAHLEDU: | ||||
|     obrazky_predchozi = obrazky[znacka-NAHLEDU:znacka] | ||||
|   else: | ||||
|     obrazky_predchozi = obrazky[0:znacka] | ||||
|    | ||||
|   # Preskalovani obrazku do vybraneho prostoru. | ||||
|   vyska = obrazek.obrazek_stredni.height | ||||
|   sirka = obrazek.obrazek_stredni.width | ||||
|   if vyska > MAX_VYSKA: | ||||
|     sirka = sirka * MAX_VYSKA / vyska   | ||||
|     vyska = MAX_VYSKA | ||||
|   if sirka > MAX_SIRKA: | ||||
|     vyska = vyska * MAX_SIRKA / sirka | ||||
|     sirka = MAX_SIRKA | ||||
| 
 | ||||
|   return render(request, 'galerie/Galerie.html', | ||||
|       {'galerie' : galerie, | ||||
|        'obrazek' : obrazek, | ||||
|        'vyska' : vyska, | ||||
|        'sirka' : sirka, | ||||
|        'obrazky_predchozi' : obrazky_predchozi, | ||||
|        'obrazky_dalsi' : obrazky_dalsi, | ||||
|        'preview' : preview, | ||||
|        'form' : form, | ||||
|       }) | ||||
| 
 | ||||
| 
 | ||||
| def new_galerie(request, galerie, soustredeni): | ||||
| 
 | ||||
|     # zjistime k jakemu soustredeni se vaze nove vytvarena galerie | ||||
|     soustredeni = get_object_or_404(Soustredeni, pk = soustredeni) | ||||
|     # pokud je parametr galerie 0, pak jde o hlavni galerii | ||||
|     # kdyz je nejaky jiny, pak je pk galerie pod kterou tu dalsi vytvarim | ||||
|     if int(galerie) == 0: | ||||
|         galerie_up = False | ||||
|         galerie_text = "Hlavní fotogalerie soustředění" | ||||
|     else: | ||||
|         galerie_up = get_object_or_404(Galerie, pk = int(galerie)) | ||||
|         galerie_text = "podgalerii ke galerii " + str(galerie_up) | ||||
| 
 | ||||
|     # obsluha formulare umoznujiciho multiple nahravani fotek | ||||
|     if request.method == 'POST': | ||||
|         form = NewGalerieForm(request.POST, request.FILES) | ||||
|         if form.is_valid(): | ||||
|             # vytvoreni nove galerie | ||||
|             gal = Galerie() | ||||
|             gal.nazev = form.cleaned_data['nazev'] | ||||
|             gal.popis = form.cleaned_data['popis'] | ||||
|             gal.zobrazit = 1 # galerie je v procesu vytvareni | ||||
|             ''' pokud je to podgalerie pridej nadrazenou galerii | ||||
|             a nadrazene soustredeni nechej volne, | ||||
|             pokud je to hlavni galerie, tak nadrazena galerie neexistuje, | ||||
|             ale v takovem pripade musi byt nadrazene soustredeni a ne jinak ''' | ||||
|             if galerie_up: | ||||
|                 gal.galerie_up = galerie_up | ||||
|             else: | ||||
|                 gal.soustredeni = soustredeni | ||||
|             gal.poradi = int(len(gal.galerie_up.galerie_set.all())) + 1  | ||||
|             gal.save() | ||||
| 
 | ||||
|             # zpracovani obrazku v galerii | ||||
|             for obr in request.FILES.getlist('obr'): | ||||
|                 o = Obrazek() | ||||
|                 o.obrazek_velky = obr | ||||
|                 o.nazev = str(obr) | ||||
|                 o.galerie = gal | ||||
|                 o.save() | ||||
| 
 | ||||
|             # presmerovani na prave vzniklou galerii | ||||
|             return HttpResponseRedirect('../../' + str(gal.pk)) | ||||
| 
 | ||||
|     else: | ||||
|         form = NewGalerieForm() | ||||
| 
 | ||||
| 
 | ||||
|     return render(request, 'galerie/GalerieNew.html', | ||||
|             { | ||||
|                 'form' : form, | ||||
|                 'soustredeni' : soustredeni, | ||||
|                 'galerie_text' : galerie_text, | ||||
|                 }) | ||||
| 
 | ||||
| def plus_galerie(request, galerie, soustredeni, subgalerie): | ||||
|     galerie = get_object_or_404(Galerie, pk=subgalerie) | ||||
|     if galerie.poradi: | ||||
|         galerie.poradi += 1 | ||||
|     else: | ||||
|         galerie.poradi = int(len(galerie.galerie_up.galerie_set.all())) | ||||
|     galerie.save() | ||||
|     return HttpResponseRedirect('../../') | ||||
| 
 | ||||
| def minus_galerie(request, galerie, soustredeni, subgalerie): | ||||
|     galerie = get_object_or_404(Galerie, pk=subgalerie) | ||||
|     if galerie.poradi: | ||||
|         galerie.poradi -= 1 | ||||
|     else: | ||||
|         galerie.poradi = 1 | ||||
|     galerie.save() | ||||
|     return HttpResponseRedirect('../../') | ||||
| 
 | ||||
|  | @ -113,6 +113,7 @@ INSTALLED_APPS = ( | |||
|     # MaMweb | ||||
|     'mamweb', | ||||
|     'seminar', | ||||
|     'galerie', | ||||
| 
 | ||||
|     # Admin upravy: | ||||
| 
 | ||||
|  |  | |||
|  | @ -408,3 +408,57 @@ div.zadani_azad_termin { | |||
| 		float: none; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* galerie */ | ||||
| 
 | ||||
| .predchozi_obrazek{ | ||||
|   position: absolute; | ||||
|   z-index: 1; | ||||
|   width: 33%; | ||||
|   height: 100%; | ||||
|   left: 0; | ||||
|   top: 0; | ||||
| } | ||||
| .predchozi_obrazek:hover{ | ||||
|   background-image: url("/static/galerie/prvky/predchozi.png"); | ||||
|   background-position: left center; | ||||
|   background-repeat: no-repeat; | ||||
| } | ||||
| .dalsi_obrazek{ | ||||
|   position: absolute; | ||||
|   z-index: 1; | ||||
|   width: 33%; | ||||
|   height: 100%; | ||||
|   left: 67%; | ||||
|   top: 0; | ||||
| } | ||||
| .dalsi_obrazek:hover{ | ||||
|   background-image: url("/static/galerie/prvky/dalsi.png"); | ||||
|   background-position: right center; | ||||
|   background-repeat: no-repeat; | ||||
| } | ||||
| 
 | ||||
| .galerie{ | ||||
|   position: relative; | ||||
| } | ||||
| .galerie_top{ | ||||
|   margin: 1em 0; | ||||
|   text-align: right; | ||||
| } | ||||
| .galerie_bot{ | ||||
|   margin: 1em 0; | ||||
| } | ||||
| .galerie_index{ | ||||
|   width: 100%; | ||||
| } | ||||
| .galerie_index td{ | ||||
|   width: 50%; | ||||
| } | ||||
| .galerie_nahled{ | ||||
|   width: 100%; | ||||
| } | ||||
| .galerie_nahled td{ | ||||
|   width: 33%; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ traitlets==4.0.0 | |||
| 
 | ||||
| # Django and modules | ||||
| 
 | ||||
| Django==1.7.10 # Updatable to 1.8 (possibly incompatible) | ||||
| Django==1.7.10 # Updatable to 1.9 (possibly incompatible) | ||||
| django-bootstrap-sass==0.0.6a0 | ||||
| django-mptt==0.7.3 | ||||
| django-reversion==1.9.3 | ||||
|  |  | |||
|  | @ -17,8 +17,6 @@ | |||
| <em> | ||||
|   Na galeriích ze soustředění a dalších informacích ještě pracujeme. | ||||
| </em><br><br> | ||||
| {#% if user.is_authenticated %#}{# PRACUJE SE STRANKA #} | ||||
| 
 | ||||
| 
 | ||||
|   {# Projdi vsechna soustredeni #} | ||||
|   {% for soustredeni in object_list %} | ||||
|  | @ -40,7 +38,25 @@ | |||
| 	<li> | ||||
| 		{{soustredeni.datum_zacatku}} – {{soustredeni.datum_konce}} | ||||
| 	</li> | ||||
|   {# Zobrazeni odkazu na galerie #} | ||||
|   {% if soustredeni.galerie_set.all %} | ||||
|     {% for galerie in soustredeni.galerie_set.all %} | ||||
|       {% if galerie.zobrazit == 0 or user.is_staff %} | ||||
|         <li> | ||||
|           <a href="../{{soustredeni.pk}}/fotogalerie/{{galerie.pk}}">FOTOGALERIE: {{galerie}}</a> | ||||
|           {# TODO kdyz je titulni obrazek, tak asi i titulni obrazek #} | ||||
|         </li> | ||||
|       {% endif %} | ||||
|     {% endfor %} | ||||
|   {% endif %} | ||||
|   {% if user.is_staff %} | ||||
|     <li> | ||||
|       <a href="../{{soustredeni.pk}}/fotogalerie/0/new/"> VYTVOŘIT NOVOU FOTOGALERII </a> | ||||
|     </li> | ||||
|   {% endif %} | ||||
| 
 | ||||
| 	</ul> | ||||
| 
 | ||||
|       {% if user.is_authenticated %} | ||||
|         {# popis soustredeni #} | ||||
|         {% if soustredeni.text %} | ||||
|  | @ -61,7 +77,5 @@ | |||
|     Žádná soustředění zatím neproběhla! | ||||
|   {% endfor %} | ||||
| 
 | ||||
| {#% else %}{% include 'seminar/pracuje_se.html' %}{% endif %#} | ||||
| 
 | ||||
| {% endblock %} | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| from django.conf.urls import *  # NOQA | ||||
| from django.conf.urls import patterns, url | ||||
| from . import views, export | ||||
| 
 | ||||
|  | @ -15,7 +16,8 @@ urlpatterns = patterns('', | |||
| 
 | ||||
|     url(r'^soustredeni/probehlo/$', views.SoustredeniListView.as_view(), | ||||
|         name = 'seminar_seznam_soustredeni'), | ||||
|     url(r'^soustredeni/(?P<pk>\d+)/$', views.SoustredeniView.as_view(), name='seminar_soustredeni'), | ||||
|     url(r'^soustredeni/probehlo/(?P<soustredeni>\d+)/$', views.SoustredeniView.as_view(), name='seminar_soustredeni'), | ||||
|     url(r'^soustredeni/(?P<soustredeni>\d+)/fotogalerie/', include('galerie.urls')), | ||||
| 
 | ||||
|     url(r'^zadani/aktualni/$', views.AktualniZadaniView, name='seminar_aktualni_zadani'), | ||||
|     url(r'^zadani/temata/$', views.ZadaniTemataView, name='seminar_temata'), | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Bc. Petr Pecha
						Bc. Petr Pecha