Veliké přejmenovávání

Myslím, že to nefunguje, ještě nejsou změněné templaty.
A není napsaná migrace
A není to zdokumentované
This commit is contained in:
LEdoian 2025-12-17 13:22:07 +00:00
parent 09f6cc6bc3
commit d06be4ccbd
10 changed files with 136 additions and 136 deletions

View file

@ -13,8 +13,7 @@ def zverejnit_fotogalerii(modeladmin, request, queryset):
for galerie in queryset: for galerie in queryset:
galerie.zobrazit = Galerie.Viditelnost.VZDY galerie.zobrazit = Galerie.Viditelnost.VZDY
galerie.save() galerie.save()
zverejnit_fotogalerii(modeladmin, request, zverejnit_fotogalerii(modeladmin, request, galerie.podgalerie.all())
Galerie.objects.filter(galerie_up = galerie))
zverejnit_fotogalerii.short_description = 'Zveřejnit fotogalerie' zverejnit_fotogalerii.short_description = 'Zveřejnit fotogalerie'
@ -24,32 +23,29 @@ def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset):
for galerie in queryset: for galerie in queryset:
galerie.zobrazit = Galerie.Viditelnost.ORG galerie.zobrazit = Galerie.Viditelnost.ORG
galerie.save() galerie.save()
prepnout_fotogalerii_do_org_rezimu(modeladmin, request, prepnout_fotogalerii_do_org_rezimu(modeladmin, request, galerie.podgalerie.all())
Galerie.objects.filter(galerie_up = galerie))
prepnout_fotogalerii_do_org_rezimu.short_description = \ prepnout_fotogalerii_do_org_rezimu.short_description = \
'Přepnout do režimu úprav (zneveřejní galerii)' 'Přepnout do režimu úprav (zneveřejní galerii)'
class GalerieInline(admin.TabularInline): class GalerieInline(admin.TabularInline):
model = Soubor model = Soubor
fields = ['soubor', 'nazev', 'popis', 'typ', 'poradi'] fields = ['soubor', 'nazev', 'popisek', 'typ', 'poradi']
readonly_fields = ['nazev'] readonly_fields = ['nazev']
formfield_overrides = { formfield_overrides = {
models.TextField: {'widget': forms.TextInput}, models.TextField: {'widget': forms.TextInput},
} }
@admin.register(Soubor)
class SouborAdmin(admin.ModelAdmin): class SouborAdmin(admin.ModelAdmin):
list_display = ('soubor', 'nazev', 'popis', 'poradi') list_display = ('soubor', 'nazev', 'popisek', 'poradi')
search_fields = ['nazev','popis'] search_fields = ['nazev','popisek']
@admin.register(Galerie)
class GalerieAdmin(admin.ModelAdmin): class GalerieAdmin(admin.ModelAdmin):
model = Galerie model = Galerie
fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi') fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'poznamka', 'nadgalerie', 'soustredeni', 'poradi')
autocomplete_fields = ['titulni_obrazek'] autocomplete_fields = ['titulni_obrazek']
list_display = ('nazev', 'soustredeni', 'galerie_up', 'poradi', 'zobrazit', 'datum_zmeny') list_display = ('nazev', 'soustredeni', 'nadgalerie', 'poradi', 'zobrazit', 'datum_zmeny')
inlines = [GalerieInline] inlines = [GalerieInline]
actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu] actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu]
save_on_top = True save_on_top = True
ordering = ['galerie_up__nazev', 'poradi']
admin.site.register(Soubor, SouborAdmin)
admin.site.register(Galerie, GalerieAdmin)

View file

@ -2,7 +2,7 @@ from django import forms
class KomentarForm(forms.Form): class KomentarForm(forms.Form):
"""Formulář na přidání/úpravu popisku u souboru (obrázku)""" """Formulář na přidání/úpravu popisku u souboru (obrázku)"""
komentar = forms.CharField(label = "Komentář:", max_length = 300, required=False) popisek = forms.CharField(label = "Popisek:", max_length = 300, required=False)
class NewGalerieForm(forms.Form): class NewGalerieForm(forms.Form):
nazev = forms.CharField(label = "Název galerie", max_length = 100) nazev = forms.CharField(label = "Název galerie", max_length = 100)

View file

@ -30,8 +30,8 @@ def galerie_filename(self, filename):
# soustředění je v cestě jen pokud galerie pod nějaké patří # soustředění je v cestě jen pokud galerie pod nějaké patří
cesta = ( cesta = (
['Galerie'] + ['Galerie'] +
(["soustredeni_{}".format(gal.soustredeni.pk)] if gal.soustredeni else []) + ([f"soustredeni_{gal.soustredeni.pk}"] if gal.soustredeni else []) +
["galerie_{}".format(cislo_gal), self.nazev] [f"galerie_{cislo_gal}", self.nazev]
) )
return os.path.join(*cesta) return os.path.join(*cesta)
@ -45,22 +45,22 @@ class Soubor(models.Model):
VIDEO = 'video', 'Video' VIDEO = 'video', 'Video'
NEVIM = 'nevim', 'Neznámý typ' NEVIM = 'nevim', 'Neznámý typ'
typ = models.CharField('Typ', max_length=16, blank=False, null=False, choices=Typ.choices, default=Typ.NEVIM) typ = models.CharField('Typ', max_length=16, blank=False, null=False, choices=Typ.choices, default=Typ.NEVIM)
# Filename by default; slouží k řazení nazev = models.CharField('Jméno souboru', max_length=50, blank=True, null=True,
nazev = models.CharField('Jméno souboru', max_length=50, blank=True, null=True) help_text="Název, slouží k řazení. Typicky není potřeba vyplnit, automaticky se použije jméno nahraného souboru.")
# ~~Rádoby~~ vtipný popisek od orgů #: ~~Rádoby~~ vtipný popisek od orgů
popis = models.TextField('Popisek', blank=True, null=True) popisek = models.TextField('Popisek', blank=True, null=True)
datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add=True) datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add=True)
galerie = models.ForeignKey('Galerie', blank=True, null=True, on_delete=models.CASCADE) galerie = models.ForeignKey('Galerie', blank=True, null=True, on_delete=models.CASCADE)
# Primární klíč k řazení pro overridování řazení podle názvu poradi = models.IntegerField('Pořadí', blank=True, null=True,
poradi = models.IntegerField('Pořadí', blank=True, null=True) help_text='Primární klíč pro řazení v rámci galerie.')
def __str__(self): def __str__(self):
return f'Soubor {self.nazev} ({self.soubor.name})' return f'Soubor {self.nazev} ({self.soubor.name})'
class Meta: class Meta:
verbose_name = 'Soubor' verbose_name = 'Soubor (Obrázek ap.)'
verbose_name_plural = 'Soubory' verbose_name_plural = 'Soubory (Obrázky ap.)'
db_table = 'galerie_obrazek' # FIXME: přejmenovat db_table = 'galerie_soubor'
ordering = ['galerie', 'poradi', 'nazev'] ordering = ['galerie', 'poradi', 'nazev']
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
@ -82,7 +82,7 @@ class Soubor(models.Model):
case _: raise ValueError("Neznámý typ obrázku, bug v kódu!") case _: raise ValueError("Neznámý typ obrázku, bug v kódu!")
def get_absolute_url(self): def get_absolute_url(self):
return reverse('galerie_soubor', pk=self.galerie.pk, fotka=self.pk) return reverse('galerie_soubor', kwargs={'galerie': self.galerie.pk, 'soubor': self.pk})
class Galerie(models.Model): class Galerie(models.Model):
class Viditelnost(models.IntegerChoices): class Viditelnost(models.IntegerChoices):
@ -95,10 +95,13 @@ class Galerie(models.Model):
datum_vytvoreni = models.DateTimeField('Datum vytvoření', auto_now_add = True) datum_vytvoreni = models.DateTimeField('Datum vytvoření', auto_now_add = True)
datum_zmeny = models.DateTimeField('Datum poslední změny', auto_now = True) datum_zmeny = models.DateTimeField('Datum poslední změny', auto_now = True)
poznamka = models.TextField('neveřejná poznámka', blank = True, null = True) poznamka = models.TextField('neveřejná poznámka', blank = True, null = True)
titulni_obrazek = models.ForeignKey(Soubor, blank = True, null = True, related_name = "+", on_delete = models.SET_NULL) titulni_obrazek = models.ForeignKey(Soubor, verbose_name = 'Titulní obrázek', blank = True, null = True, related_name = "+", on_delete = models.SET_NULL)
zobrazit = models.IntegerField('Zobrazit?', default = Viditelnost.ORG, choices = Viditelnost.choices) # TODO: Dj5 už stačí `choices = Viditelnost` zobrazit = models.IntegerField('Zobrazit?', default = Viditelnost.ORG, choices = Viditelnost.choices) # TODO: Dj5 už stačí `choices = Viditelnost`
galerie_up = models.ForeignKey('Galerie', blank = True, null = True, #: None pro hlavní galerie soustředění
nadgalerie = models.ForeignKey('Galerie', verbose_name = 'Nadgalerie', blank = True, null = True,
related_name='podgalerie',
on_delete=models.PROTECT) on_delete=models.PROTECT)
#: None pro podgalerie, not None pro hlavní galerie soustředění
soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True, soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True,
on_delete=models.PROTECT) on_delete=models.PROTECT)
poradi = models.IntegerField('Pořadí', blank = True, null = False, default = 0) poradi = models.IntegerField('Pořadí', blank = True, null = False, default = 0)
@ -109,6 +112,7 @@ class Galerie(models.Model):
verbose_name = 'Galerie' verbose_name = 'Galerie'
verbose_name_plural = 'Galerie' verbose_name_plural = 'Galerie'
db_table = 'galerie_galerie' db_table = 'galerie_galerie'
ordering = ['nadgalerie__datum_vytvoreni', 'poradi', 'nazev']
def get_absolute_url(self): def get_absolute_url(self):
return reverse('galerie_galerie', pk=self.pk) return reverse('galerie_galerie', kwargs={'galerie': self.pk})

View file

@ -3,7 +3,7 @@
{% load bazmeky %} {% load bazmeky %}
{% block nadpis1a %} {% block nadpis1a %}
{{galerie.nazev}}: {{ obrazek.popis | default:"Fotka" }} {{galerie.nazev}}: {{ obrazek.popisek | default:"Fotka" }}
{% endblock %} {% endblock %}
@ -21,17 +21,17 @@
{% if predchozi_obrazek %} {% if predchozi_obrazek %}
// doleva // doleva
if (e.which == 37) { if (e.which == 37) {
window.location.assign("{% url 'galerie_soubor' pk=galerie.pk fotka=predchozi_obrazek.pk %}#nahoru"); window.location.assign("{% url 'galerie_soubor' galerie=galerie.pk soubor=predchozi_obrazek.pk %}#nahoru");
} }
{% endif %} {% endif %}
{% if dalsi_obrazek %} {% if dalsi_obrazek %}
// doprava // doprava
if (e.which == 39) { if (e.which == 39) {
window.location.assign("{% url 'galerie_soubor' pk=galerie.pk fotka=dalsi_obrazek.pk %}#nahoru"); window.location.assign("{% url 'galerie_soubor' galerie=galerie.pk soubor=dalsi_obrazek.pk %}#nahoru");
} }
{% endif %} {% endif %}
if (e.which == 27) { if (e.which == 27) {
window.location.assign("{% url 'galerie_galerie' pk=galerie.pk %}#obsah"); window.location.assign("{% url 'galerie_galerie' galerie=galerie.pk %}#obsah");
} }
}); });
@ -51,7 +51,7 @@
<h2> <h2>
{% for g in cesta %} {% for g in cesta %}
<a href="{% url 'galerie_galerie' pk=g.pk %}">{{ g.nazev }}</a>{% if not forloop.last %} >{% endif %} <a href="{% url 'galerie_galerie' galerie=g.pk %}">{{ g.nazev }}</a>{% if not forloop.last %} >{% endif %}
{% endfor %} {% endfor %}
</h2> </h2>
@ -60,17 +60,17 @@
{% if obrazky_predchozi %} {% if obrazky_predchozi %}
{% with obrazky_predchozi|last as predchozi_obrazek %} {% with obrazky_predchozi|last as predchozi_obrazek %}
<div> <div>
<a title="Předchozí" class="predchozi_obrazek" href="{% url 'galeie_soubor' pk=galerie.pk fotka=predchozi_obrazek.pk %}#nahoru"></a> <a title="Předchozí" class="predchozi_obrazek" href="{% url 'galeie_soubor' galerie=galerie.pk soubor=predchozi_obrazek.pk %}#nahoru"></a>
</div> </div>
{% endwith %} {% endwith %}
{% endif%} {% endif%}
<span id="nahoru" class="kotva_obrazku"></span> <span id="nahoru" class="kotva_obrazku"></span>
{% zobrazit obrazek.jako_bazmek alt=obrazek.popis title=obrazek.popis class="obrazek" %} {% zobrazit obrazek.jako_bazmek alt=obrazek.popisek title=obrazek.popisek class="obrazek" %}
{% if obrazky_dalsi %} {% if obrazky_dalsi %}
{% with obrazky_dalsi|first as dalsi_obrazek %} {% with obrazky_dalsi|first as dalsi_obrazek %}
<div> <div>
<a title="Další" class="dalsi_obrazek" href="{% url 'galerie_soubor' pk=galerie.pk fotka=dalsi_obrazek.pk %}#nahoru"></a> <a title="Další" class="dalsi_obrazek" href="{% url 'galerie_soubor' galerie=galerie.pk soubor=dalsi_obrazek.pk %}#nahoru"></a>
</div> </div>
{% endwith %} {% endwith %}
{% endif%} {% endif%}
@ -85,14 +85,14 @@
<form action=".#nahoru" method="post" id="komentarform"> <form action=".#nahoru" method="post" id="komentarform">
{% csrf_token %} {% csrf_token %}
<table> <table>
<tr><td><label>Aktuální komentář:</label></td><td>{{obrazek.popis}}</td> <tr><td><label>Aktuální komentář:</label></td><td>{{obrazek.popisek}}</td>
{{form.as_table}} {{form.as_table}}
<tr><td></td><td><input name="odeslat" type="submit" value="Změň komentář"></td></tr> <tr><td></td><td><input name="odeslat" type="submit" value="Změň komentář"></td></tr>
</table> </table>
</form> </form>
{% else %} {% else %}
{% if obrazek.popis %} {% if obrazek.popisek %}
{{obrazek.popis}} {{obrazek.popisek}}
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>
@ -101,24 +101,24 @@
{# odkaz na predchozi galerii #} {# odkaz na predchozi galerii #}
<div class="navigace"> <div class="navigace">
{% if predchozi_galerie %} {% if predchozi_galerie %}
Předchozí: <a href="{% url 'galerie_soubor' pk=predchozi_galerie.pk fotka=predchozi_galerie.obrazek_set.last.pk %}#nahoru"> Předchozí: <a href="{% url 'galerie_soubor' galerie=predchozi_galerie.pk soubor=predchozi_galerie.obrazek_set.last.pk %}#nahoru">
{{predchozi_galerie}} {{predchozi_galerie}}
</a> </a>
{% endif %} {% endif %}
{# nahledy predchozich obrazku #} {# nahledy predchozich obrazku #}
{% for obrazek in obrazky_predchozi %} {% for obrazek in obrazky_predchozi %}
<a href="{% url 'galerie_soubor' pk=galerie.pk fotka=obrazek.pk %}#nahoru">{% zmenseny_nahled obrazek.jako_bazmek height=100 %}</a> <a href="{% url 'galerie_soubor' galerie=galerie.pk soubor=obrazek.pk %}#nahoru">{% zmenseny_nahled obrazek.jako_bazmek height=100 %}</a>
{% endfor %} {% endfor %}
{% zmenseny_nahled obrazek.jako_bazmek alt=obrazek.popis class="obrazek" id="prostredni" %} {% zmenseny_nahled obrazek.jako_bazmek alt=obrazek.popisek class="obrazek" id="prostredni" %}
{# nahledy nasledujicich obrazku #} {# nahledy nasledujicich obrazku #}
{% for obrazek in obrazky_dalsi %} {% for obrazek in obrazky_dalsi %}
<a href="{% url 'galerie_soubor' pk=galerie.pk fotka=obrazek.pk %}#nahoru">{% zmenseny_nahled obrazek.jako_bazmek height=100 %}</a> <a href="{% url 'galerie_soubor' galerie=galerie.pk soubor=obrazek.pk %}#nahoru">{% zmenseny_nahled obrazek.jako_bazmek height=100 %}</a>
{% endfor %} {% endfor %}
{# odkaz na nasledujici galerii #} {# odkaz na nasledujici galerii #}
{% if nasledujici_galerie %} {% if nasledujici_galerie %}
Následující: <a href="{% url 'galerie_soubor' pk=nasledujici_galerie.pk fotka=nasledujici_galerie.obrazek_set.first.pk %}#nahoru"> Následující: <a href="{% url 'galerie_soubor' galerie=nasledujici_galerie.pk soubor=nasledujici_galerie.obrazek_set.first.pk %}#nahoru">
{{nasledujici_galerie}} {{nasledujici_galerie}}
</a> </a>
{% endif %} {% endif %}

View file

@ -3,7 +3,7 @@
{% load bazmeky %} {% load bazmeky %}
{% block nadpis1a %} {% block nadpis1a %}
Galerie {{galerie.nazev}} Galerie popisekgalerie.nazev}}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
@ -18,7 +18,7 @@ Galerie {{galerie.nazev}}
<h2> <h2>
{% for g in cesta %} {% for g in cesta %}
{% if not forloop.last %} {% if not forloop.last %}
<a href="{% url 'galerie_galerie pk=g.pk %}">{{ g.nazev }}</a> > <a href="{% url 'galerie_galerie galerie=g.pk %}">{{ g.nazev }}</a> >
{% else %} {% else %}
{{ g.nazev }} {{ g.nazev }}
{% endif %} {% endif %}
@ -39,7 +39,7 @@ Galerie {{galerie.nazev}}
{% if sourozenci|length > 1 %} {% if sourozenci|length > 1 %}
{% for g in sourozenci %} {% for g in sourozenci %}
{% if g.pk != galerie.pk %} {% if g.pk != galerie.pk %}
<a href="{% url 'galerie_galerie' pk=g.pk %}">{{ g.nazev }}</a> <a href="{% url 'galerie_galerie' galerie=g.pk %}">{{ g.nazev }}</a>
{% else %} {% else %}
{{ g.nazev }} {{ g.nazev }}
{% endif %} {% endif %}
@ -51,7 +51,7 @@ Galerie {{galerie.nazev}}
{% with 22 as max_delka_nazvu %} {% with 22 as max_delka_nazvu %}
<div class="galerie_nahledy"> <div class="galerie_nahledy">
{% for pgalerie in podgalerie %} {% for pgalerie in podgalerie %}
<a href="{% url 'galerie_galerie' pk=pgalerie.pk %}" <a href="{% url 'galerie_galerie' galerie=pgalerie.pk %}"
{% if pgalerie.nazev|length > max_delka_nazvu %} {% if pgalerie.nazev|length > max_delka_nazvu %}
title="{{ pgalerie.nazev }}" title="{{ pgalerie.nazev }}"
{% endif %} {% endif %}
@ -67,8 +67,8 @@ Galerie {{galerie.nazev}}
{% if user.je_org %} {% if user.je_org %}
<div class="mam-org-only-galerie"> <div class="mam-org-only-galerie">
({{pgalerie.poradi}}) ({{pgalerie.poradi}})
<span class="plus"><a href="{% url 'galerie_plus' galerie=galerie.pk subgalerie=pgalerie.pk %}">+</a></span> <span class="plus"><a href="{% url 'galerie_doprava' galerie=galerie.pk subgalerie=pgalerie.pk %}">+</a></span>
<span class="minus"><a href="{% url 'galerie_minus' galerie=galerie.pk subgalerie=pgalerie.pk %}">-</a></span> <span class="minus"><a href="{% url 'galerie_doleva' galerie=galerie.pk subgalerie=pgalerie.pk %}">-</a></span>
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
@ -92,13 +92,13 @@ Galerie {{galerie.nazev}}
<div class="galerie_nahledy"> <div class="galerie_nahledy">
{% for obrazek in obrazky %} {% for obrazek in obrazky %}
<a <a
{% if obrazek.popis %} {% if obrazek.popisek %}
title="{{ obrazek.popis }}" title="{{ obrazek.popisek }}"
{% endif %} {% endif %}
href="{% url 'galerie_soubor' pk=galerie.pk fotka=obrazek.pk %}#nahoru" class="galerie_nahled"> href="{% url 'galerie_soubor' galerie=galerie.pk soubor=obrazek.pk %}#nahoru" class="galerie_nahled">
<span class="vystredeno"></span> <span class="vystredeno"></span>
{% zmenseny_nahled obrazek.jako_bazmek %} {% zmenseny_nahled obrazek.jako_bazmek %}
{# title=obrazek.popis (a byl tu if, že se použil jen když existoval…) width=obrazek.obrazek_maly.width height=obrazek.obrazek_maly.height #} {# title=obrazek.popisek (a byl tu if, že se použil jen když existoval…) width=obrazek.obrazek_maly.width height=obrazek.obrazek_maly.height #}
</a> </a>
{% endfor %} {% endfor %}
<br> <br>
@ -107,12 +107,12 @@ Galerie {{galerie.nazev}}
<div class="galerie_predchozi_nasledujici"> <div class="galerie_predchozi_nasledujici">
{% if predchozi %} {% if predchozi %}
<div class="predchozi"> <div class="predchozi">
<a href="{% url 'galerie_galerie' pk=predchozi.pk %}">Předchozí: {{ predchozi.nazev }}</a> <a href="{% url 'galerie_galerie' galerie=predchozi.pk %}">Předchozí: {{ predchozi.nazev }}</a>
</div> </div>
{% endif %} {% endif %}
{% if nasledujici %} {% if nasledujici %}
<div class="nasledujici"> <div class="nasledujici">
<a href="{% url 'galerie_galerie' pk=nasledujici.pk %}">Následující: {{ nasledujici.nazev }}</a> <a href="{% url 'galerie_galerie' galerie=nasledujici.pk %}">Následující: {{ nasledujici.nazev }}</a>
</div> </div>
{% endif %} {% endif %}
</div> </div>

View file

@ -1,5 +1,5 @@
""" """
Pomocné tagy pro zobrazování `galerie.typy.ZobrazitelnyBazmek`. Jen volají příslušnou metodu na bazmeku. Pomocné tagy pro zobrazování :py:class:`galerie.typy.ZobrazitelnyBazmek`. Jen volají příslušnou metodu na bazmeku.
""" """
from django import template from django import template
register = template.Library() register = template.Library()

View file

@ -40,7 +40,7 @@ class ZobrazitelnyBazmek(abc.ABC):
... ...
@abc.abstractmethod @abc.abstractmethod
def zmenseny_nahled(self, **kwargs) -> HTML: def zmenseny_nahled(self, **kwargs) -> HTML:
"""Zmenšené obrázky v přehledu obrázků a pod hlavním obrázkem (předchozí/následující)""" """Zmenšené obrázky v přehledu obrázků a v navigaci pod hlavním obrázkem"""
... ...
@property @property
@ -54,7 +54,7 @@ class ZobrazitelnyBazmek(abc.ABC):
### Obrázky ### ### Obrázky ###
# Odpovídá původnímu chování (bo se mi nechce vymýšlet novoty… # Odpovídá původnímu chování (bo se mi nechce vymýšlet novoty…
class ObrazekStredniSpec(ImageSpec): class ObrazekSpec(ImageSpec):
"""Specifikace obrázku pro velké zobrazení""" """Specifikace obrázku pro velké zobrazení"""
processors = [ processors = [
Transpose(Transpose.AUTO), # Rotuj podle dat v EXIFu Transpose(Transpose.AUTO), # Rotuj podle dat v EXIFu
@ -63,7 +63,7 @@ class ObrazekStredniSpec(ImageSpec):
format = 'JPEG' format = 'JPEG'
options = {'quality': 95} # Proč tolik? options = {'quality': 95} # Proč tolik?
class ObrazekMalySpec(ImageSpec): class ObrazekZmensenySpec(ImageSpec):
"""Specifikace obrázku pro náhledy (pod hlavním obrázkem nebo v přehledu galerie)""" """Specifikace obrázku pro náhledy (pod hlavním obrázkem nebo v přehledu galerie)"""
processors = [ processors = [
Transpose(Transpose.AUTO), Transpose(Transpose.AUTO),
@ -85,14 +85,14 @@ class Obrazek(ZobrazitelnyBazmek):
""" """
def zobrazit(self, **kwargs): def zobrazit(self, **kwargs):
# Jak se takový cachefile používá je potřeba vyčíst ze zdrojáků? # Jak se takový cachefile používá je potřeba vyčíst ze zdrojáků?
file = ImageCacheFile(ObrazekStredniSpec(source=self.soubor)) file = ImageCacheFile(ObrazekSpec(source=self.soubor))
file.generate() file.generate()
attrs = _fmt_attrs(kwargs) attrs = _fmt_attrs(kwargs)
html = format_html(r'<img src="{}" {} />', file.url, attrs) html = format_html(r'<img src="{}" {} />', file.url, attrs)
return html return html
def zmenseny_nahled(self, **kwargs): def zmenseny_nahled(self, **kwargs):
file = ImageCacheFile(ObrazekMalySpec(source=self.soubor)) file = ImageCacheFile(ObrazekZmensenySpec(source=self.soubor))
file.generate() file.generate()
attrs = _fmt_attrs(kwargs) attrs = _fmt_attrs(kwargs)
html = format_html(r'<img src="{}" {} />', file.url, attrs) html = format_html(r'<img src="{}" {} />', file.url, attrs)

View file

@ -3,10 +3,10 @@ from personalni.utils import org_required
from . import views from . import views
urlpatterns = [ urlpatterns = [
path('<int:pk>/', views.nahled, name='galerie_galerie'), path('<int:galerie>/', views.galerieView, name='galerie_galerie'),
path('<int:pk>/<int:fotka>/', views.detail, name='galerie_soubor'), path('<int:galerie>/<int:soubor>/', views.souborView, name='galerie_soubor'),
path('<int:galerie>/new/', org_required(views.new_galerie), name='galerie_nova'), path('<int:galerie>/new/', org_required(views.new_galerie), name='galerie_nova'),
path('<int:galerie>/plus/<int:subgalerie>/', org_required(views.plus_galerie), name='galerie_plus'), path('<int:galerie>/doprava/<int:subgalerie>/', org_required(views.galerie_doprava), name='galerie_doprava'),
path('<int:galerie>/minus/<int:subgalerie>/', org_required(views.minus_galerie), name='galerie_minus'), path('<int:galerie>/doleva/<int:subgalerie>/', org_required(views.galerie_doleva), name='galerie_doleva'),
] ]

View file

@ -5,6 +5,6 @@ if TYPE_CHECKING:
# Miluju pythoní typing :-P # Miluju pythoní typing :-P
def top_galerie(g: Galerie) -> Galerie: def top_galerie(g: Galerie) -> Galerie:
while g.galerie_up is not None: while g.nadgalerie is not None:
g = g.galerie_up g = g.nadgalerie
return g return g

View file

@ -3,6 +3,7 @@ import random
from django.http import HttpResponse, Http404, HttpRequest from django.http import HttpResponse, Http404, HttpRequest
from django.shortcuts import render, HttpResponseRedirect, get_object_or_404 from django.shortcuts import render, HttpResponseRedirect, get_object_or_404
from django.template import RequestContext from django.template import RequestContext
from django.urls import reverse
from datetime import datetime from datetime import datetime
from galerie.utils import top_galerie from galerie.utils import top_galerie
@ -20,7 +21,7 @@ UCASTNIK = Galerie.Viditelnost.UCASTNIK
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def galerie_ke_zobrazeni(soustredeni: Soustredeni | None, request: HttpRequest) -> tuple[int]: def galerie_ke_zobrazeni(soustredeni: Soustredeni | None, request: HttpRequest) -> tuple[Galerie.Viditelnost, ...]:
if request.user.is_superuser: return (VZDY, ORG, UCASTNIK) if request.user.is_superuser: return (VZDY, ORG, UCASTNIK)
if request.user.je_org: return (VZDY, ORG, UCASTNIK) if request.user.je_org: return (VZDY, ORG, UCASTNIK)
if request.user.is_anonymous: return (VZDY,) if request.user.is_anonymous: return (VZDY,)
@ -33,7 +34,6 @@ def galerie_ke_zobrazeni(soustredeni: Soustredeni | None, request: HttpRequest)
logger.warning("Nepodařilo se zjistit, jaké galerie se mají zobrazit!") logger.warning("Nepodařilo se zjistit, jaké galerie se mají zobrazit!")
return (VZDY,) return (VZDY,)
def zobrazit(galerie: Galerie, request: HttpRequest) -> bool: def zobrazit(galerie: Galerie, request: HttpRequest) -> bool:
soustredeni = top_galerie(galerie).soustredeni soustredeni = top_galerie(galerie).soustredeni
return galerie.zobrazit in galerie_ke_zobrazeni(soustredeni, request) return galerie.zobrazit in galerie_ke_zobrazeni(soustredeni, request)
@ -42,32 +42,32 @@ def dovolit_upravy_popisku(galerie: Galerie, request: HttpRequest) -> bool:
# FIXME: Dočasné: úpravy jen když je to v org-only stavu. (Odpovídá předchozímu chování) # FIXME: Dočasné: úpravy jen když je to v org-only stavu. (Odpovídá předchozímu chování)
return request.user.je_org and galerie.zobrazit in (ORG,) return request.user.je_org and galerie.zobrazit in (ORG,)
def cesta_od_korene(g): def cesta_od_korene(g):
"""Vrátí seznam galerií od kořene ke g""" """Vrátí seznam galerií od kořene ke g"""
cesta = [] cesta = []
while g is not None: while g is not None:
cesta.append(g) cesta.append(g)
g = g.galerie_up g = g.nadgalerie
return reversed(cesta) return reversed(cesta)
def nahled(request, pk, soustredeni): def galerieView(request, soustredeni:int, galerie: int):
"""Zobrazeni nahledu vsech fotek ve skupine.""" """Zobrazení přehledu všech souborů v Galerii."""
galerie = get_object_or_404(Galerie, pk=pk) galerie: Galerie = get_object_or_404(Galerie, pk=galerie)
soustredeni = top_galerie(galerie).soustredeni assert top_galerie(galerie).soustredeni.id == soustredeni
soustredeni: Soustredeni | None = top_galerie(galerie).soustredeni
# FIXME: přepsat model a použít přímo dolů… # FIXME: přepsat model a použít přímo dolů…
podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi') podgalerie = Galerie.objects.filter(nadgalerie = galerie).order_by('poradi')
podgalerie = podgalerie.filter(zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)) podgalerie = podgalerie.filter(zobrazit__in=galerie_ke_zobrazeni(soustredeni, request))
obrazky = galerie.soubor_set.all().order_by('poradi', 'nazev') soubory = galerie.soubor_set.all().order_by('poradi', 'nazev')
ma_se_zobrazit = zobrazit(galerie, request) ma_se_zobrazit = zobrazit(galerie, request)
if not ma_se_zobrazit: raise Http404("Galerie sice existuje, ale my se tváříme, že ne :-D") if not ma_se_zobrazit: raise Http404("Galerie sice existuje, ale my se tváříme, že ne :-D")
sourozenci = [] sourozenci = []
if galerie.galerie_up: if galerie.nadgalerie:
sourozenci = galerie.galerie_up.galerie_set.filter(zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)).order_by('poradi') sourozenci = galerie.nadgalerie.podgalerie.filter(zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)).order_by('poradi')
predchozi = None predchozi = None
nasledujici = None nasledujici = None
@ -85,7 +85,7 @@ def nahled(request, pk, soustredeni):
return render(request, 'galerie/GalerieNahled.html', return render(request, 'galerie/GalerieNahled.html',
{'galerie' : galerie, {'galerie' : galerie,
'podgalerie' : podgalerie, 'podgalerie' : podgalerie,
'obrazky' : obrazky, 'soubory' : soubory,
'cesta': cesta, 'cesta': cesta,
'sourozenci': sourozenci, 'sourozenci': sourozenci,
'predchozi': predchozi, 'predchozi': predchozi,
@ -93,31 +93,32 @@ def nahled(request, pk, soustredeni):
'object': galerie, 'object': galerie,
}) })
def detail(request, pk, fotka, soustredeni): def souborView(request, soustredeni: int, galerie: int, soubor: int):
"""Zobrazeni nahledu fotky s id 'fotka'.""" """Zobrazení souboru."""
NAHLEDU = 1 NAHLEDU = 1
galerie = get_object_or_404(Galerie, pk=pk) galerie: Galerie = get_object_or_404(Galerie, pk=galerie)
soustredeni = top_galerie(galerie).soustredeni assert top_galerie(galerie).soustredeni.id == soustredeni
soustredeni: Soustredeni | None = top_galerie(galerie).soustredeni
ma_se_zobrazit = zobrazit(galerie, request) ma_se_zobrazit = zobrazit(galerie, request)
if not ma_se_zobrazit: raise Http404("Obrázek neukážu!") if not ma_se_zobrazit: raise Http404("Obrázek neukážu!")
obrazek = get_object_or_404(Soubor, pk=fotka) soubor = get_object_or_404(Soubor, pk=soubor)
# Pořadí není povinné. FIXME: `nazev` je zavádějící… Ale tohle je kanonické pořadí obrázků v galerii… # Explicitní pořadí ničemu neuškodí :-)
obrazky = galerie.soubor_set.all().order_by('poradi', 'nazev') soubory = galerie.soubor_set.all().order_by('poradi', 'nazev')
obrazky = list(obrazky) soubory = list(soubory)
index_obrazku = obrazky.index(obrazek) index_souboru = soubory.index(soubor)
# Podle mě se nemůže stát, že by volání výš selhalo, kdyžtak shodí web. (původně to byl explicitně ošetřený stav dávající 404) # Podle mě se nemůže stát, že by volání výš selhalo, kdyžtak shodí web. (původně to byl explicitně ošetřený stav dávající 404)
predchozi_obrazky = list(reversed(obrazky[:index_obrazku])) predchozi_soubory = list(reversed(soubor[:index_souboru]))
nasledujici_obrazky = obrazky[index_obrazku+1:] nasledujici_soubory = soubory[index_souboru+1:]
# Může jich být hodně… # Může jich být hodně…
predchozi_obrazky = predchozi_obrazky[:NAHLEDU] predchozi_soubory = predchozi_soubory[:NAHLEDU]
nasledujici_obrazky = nasledujici_obrazky[:NAHLEDU] nasledujici_soubory = nasledujici_soubory[:NAHLEDU]
# Předchozí obrázky chceme v normálním pořadí # Předchozí obrázky chceme v normálním pořadí
predchozi_obrazky = list(reversed(predchozi_obrazky)) predchozi_soubory = list(reversed(predchozi_soubory))
if galerie.galerie_up is not None: if galerie.nadgalerie is not None:
sousedni_galerie = Galerie.objects.filter(galerie_up=galerie.galerie_up, zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)).order_by('poradi') sousedni_galerie = Galerie.objects.filter(nadgalerie=galerie.nadgalerie, zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)).order_by('poradi')
sousedni_galerie = list(sousedni_galerie) sousedni_galerie = list(sousedni_galerie)
# Teoreticky se můžeme dívat na galerie.poradi, ale jednak už tenhle pattern stejně je výš a druhak je galerií málo, takže pomalost nevadí. # Teoreticky se můžeme dívat na galerie.poradi, ale jednak už tenhle pattern stejně je výš a druhak je galerií málo, takže pomalost nevadí.
index_galerie = sousedni_galerie.index(galerie) index_galerie = sousedni_galerie.index(galerie)
@ -129,45 +130,45 @@ def detail(request, pk, fotka, soustredeni):
# Pokud je obrázků dost, tak další galerii nepotřebujeme # Pokud je obrázků dost, tak další galerii nepotřebujeme
# (jo, mohli jsme si ušetřit práci, ale takhle je kód imho přehlednější a za pár ušetřených dotazů do DB to nestojí) # (jo, mohli jsme si ušetřit práci, ale takhle je kód imho přehlednější a za pár ušetřených dotazů do DB to nestojí)
if len(predchozi_obrazky) >= NAHLEDU: if len(predchozi_soubory) >= NAHLEDU:
predchozi_galerie = None predchozi_galerie = None
if len(nasledujici_obrazky) >= NAHLEDU: if len(nasledujici_soubory) >= NAHLEDU:
nasledujici_galerie = None nasledujici_galerie = None
# vytvoreni a obslouzeni formulare # vytvoreni a obslouzeni formulare
if request.method == 'POST': if request.method == 'POST':
form = KomentarForm(request.POST) form = KomentarForm(request.POST)
if form.is_valid(): if form.is_valid():
obrazek.popis = form.cleaned_data['komentar'] soubor.popisek = form.cleaned_data['popisek']
obrazek.save() soubor.save()
else: else:
form = KomentarForm({'komentar': obrazek.popis}) form = KomentarForm({'popisek': soubor.popisek})
return render(request, 'galerie/Galerie.html', return render(request, 'galerie/Galerie.html',
{'galerie' : galerie, {'galerie' : galerie,
'predchozi_galerie' : predchozi_galerie, 'predchozi_galerie' : predchozi_galerie,
'nasledujici_galerie' : nasledujici_galerie, 'nasledujici_galerie' : nasledujici_galerie,
'obrazek' : obrazek, 'soubor' : soubor,
'obrazky_predchozi' : predchozi_obrazky, 'soubory_predchozi' : predchozi_soubory,
'obrazky_dalsi' : nasledujici_obrazky, 'soubory_dalsi' : nasledujici_soubory,
'upravy_popisku' : dovolit_upravy_popisku(galerie, request), 'upravy_popisku' : dovolit_upravy_popisku(galerie, request),
'form' : form, 'form' : form,
'cesta': cesta_od_korene(galerie), 'cesta': cesta_od_korene(galerie),
'object': obrazek, 'object': soubor,
}) })
def new_galerie(request, galerie, soustredeni): def new_galerie(request, galerie: int, soustredeni: int):
# zjistime k jakemu soustredeni se vaze nove vytvarena galerie # zjistime k jakemu soustredeni se vaze nove vytvarena galerie
soustredeni = get_object_or_404(Soustredeni, pk = soustredeni) soustredeni: Soustredeni = get_object_or_404(Soustredeni, pk = soustredeni)
# pokud je parametr galerie 0, pak jde o hlavni galerii # pokud je parametr galerie 0, pak jde o hlavni galerii
# kdyz je nejaky jiny, pak je pk galerie pod kterou tu dalsi vytvarim # kdyz je nejaky jiny, pak je pk galerie pod kterou tu dalsi vytvarim
if int(galerie) == 0: if int(galerie) == 0:
galerie_up = False nadgalerie = False
galerie_text = "Hlavní fotogalerie soustředění" galerie_text = "Hlavní fotogalerie soustředění"
else: else:
galerie_up = get_object_or_404(Galerie, pk = int(galerie)) nadgalerie = get_object_or_404(Galerie, pk = int(galerie))
galerie_text = "podgalerii ke galerii " + str(galerie_up) galerie_text = "podgalerii ke galerii " + str(nadgalerie)
# obsluha formulare umoznujiciho multiple nahravani fotek # obsluha formulare umoznujiciho multiple nahravani fotek
if request.method == 'POST': if request.method == 'POST':
@ -176,21 +177,20 @@ def new_galerie(request, galerie, soustredeni):
# vytvoreni nove galerie # vytvoreni nove galerie
gal = Galerie() gal = Galerie()
gal.nazev = form.cleaned_data['nazev'] gal.nazev = form.cleaned_data['nazev']
#gal.popis = form.cleaned_data['popis'] # popis nepouzivame
gal.zobrazit = ORG # galerie je v procesu vytvareni gal.zobrazit = ORG # galerie je v procesu vytvareni
''' pokud je to podgalerie pridej nadrazenou galerii ''' pokud je to podgalerie pridej nadrazenou galerii
a nadrazene soustredeni nechej volne, a nadrazene soustredeni nechej volne,
pokud je to hlavni galerie, tak nadrazena galerie neexistuje, pokud je to hlavni galerie, tak nadrazena galerie neexistuje,
ale v takovem pripade musi byt nadrazene soustredeni a ne jinak ''' ale v takovem pripade musi byt nadrazene soustredeni a ne jinak '''
if galerie_up: if nadgalerie:
gal.galerie_up = galerie_up gal.nadgalerie = nadgalerie
else: else:
gal.soustredeni = soustredeni gal.soustredeni = soustredeni
if gal.galerie_up: if gal.nadgalerie:
gal.poradi = int(len(gal.galerie_up.galerie_set.all())) + 1 gal.poradi = int(len(gal.nadgalerie.galerie_set.all())) + 1
gal.save() gal.save()
# zpracovani obrazku v galerii # zpracovani souboru v galerii
from galerie.typy import tipniTyp from galerie.typy import tipniTyp
for obr in request.FILES.getlist('obr'): for obr in request.FILES.getlist('obr'):
o = Soubor() o = Soubor()
@ -201,12 +201,11 @@ def new_galerie(request, galerie, soustredeni):
o.save() o.save()
# presmerovani na prave vzniklou galerii # presmerovani na prave vzniklou galerii
return HttpResponseRedirect('../../' + str(gal.pk)) return HttpResponseRedirect(reverse('galerie_galerie', kwargs={'galerie': gal.pk}))
else: else:
form = NewGalerieForm() form = NewGalerieForm()
return render(request, 'galerie/GalerieNew.html', return render(request, 'galerie/GalerieNew.html',
{ {
'form' : form, 'form' : form,
@ -214,21 +213,22 @@ def new_galerie(request, galerie, soustredeni):
'galerie_text' : galerie_text, 'galerie_text' : galerie_text,
}) })
def plus_galerie(request, galerie, soustredeni, subgalerie): def galerie_doprava(request, soustredeni: int, galerie: int, subgalerie: int):
galerie = get_object_or_404(Galerie, pk=subgalerie) subgalerie: Galerie = get_object_or_404(Galerie, pk=subgalerie)
if galerie.poradi: assert subgalerie.nadgalerie.pk == galerie
galerie.poradi += 1 if subgalerie.poradi:
subgalerie.poradi += 1
else: else:
galerie.poradi = int(len(galerie.galerie_up.galerie_set.all())) subgalerie.poradi = int(len(subgalerie.nadgalerie.galerie_set.all()))
galerie.save() subgalerie.save()
return HttpResponseRedirect('../../') return HttpResponseRedirect(reverse('galerie_galerie', kwargs={'galerie': galerie}))
def minus_galerie(request, galerie, soustredeni, subgalerie): def galerie_doleva(request, soustredeni: int, galerie: int, subgalerie: int):
galerie = get_object_or_404(Galerie, pk=subgalerie) subgalerie: Galerie = get_object_or_404(Galerie, pk=subgalerie)
if galerie.poradi: assert subgalerie.nadgalerie.pk == galerie
galerie.poradi -= 1 if subgalerie.poradi:
subgalerie.poradi -= 1
else: else:
galerie.poradi = 1 subgalerie.poradi = 1
galerie.save() subgalerie.save()
return HttpResponseRedirect('../../') return HttpResponseRedirect(reverse('galerie_galerie', kwargs={'galerie': galerie}))