Veliké přejmenovávání [WIP]

Neříkám, že to funguje, ale říkám, že mi běží netriviální testy :-)
Chybí:
- migrace
- přejmenovat templates
This commit is contained in:
LEdoian 2025-12-19 07:06:34 +00:00
parent d06be4ccbd
commit 1f499a00a1
10 changed files with 181 additions and 30 deletions

View file

@ -20,8 +20,8 @@ def obrazek_filename():
def obrazek_filename_velky(): def obrazek_filename_velky():
pass pass
def galerie_filename(self, filename): def galerie_filename(soubor, filename):
gal = self.galerie gal = soubor.galerie
cislo_gal = gal.pk cislo_gal = gal.pk
# najdi kořenovou galerii # najdi kořenovou galerii
@ -31,7 +31,7 @@ def galerie_filename(self, filename):
cesta = ( cesta = (
['Galerie'] + ['Galerie'] +
([f"soustredeni_{gal.soustredeni.pk}"] if gal.soustredeni else []) + ([f"soustredeni_{gal.soustredeni.pk}"] if gal.soustredeni else []) +
[f"galerie_{cislo_gal}", self.nazev] [f"galerie_{cislo_gal}", soubor.nazev]
) )
return os.path.join(*cesta) return os.path.join(*cesta)
@ -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', kwargs={'galerie': self.galerie.pk, 'soubor': self.pk}) return reverse('galerie_soubor', kwargs={'soustredeni': top_galerie(self.galerie).soustredeni.id, 'galerie': self.galerie.pk, 'soubor': self.pk})
class Galerie(models.Model): class Galerie(models.Model):
class Viditelnost(models.IntegerChoices): class Viditelnost(models.IntegerChoices):
@ -115,4 +115,4 @@ class Galerie(models.Model):
ordering = ['nadgalerie__datum_vytvoreni', 'poradi', 'nazev'] ordering = ['nadgalerie__datum_vytvoreni', 'poradi', 'nazev']
def get_absolute_url(self): def get_absolute_url(self):
return reverse('galerie_galerie', kwargs={'galerie': self.pk}) return reverse('galerie_galerie', kwargs={'soustredeni': top_galerie(self).soustredeni.id, 'galerie': self.pk})

View file

@ -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' galerie=galerie.pk soubor=predchozi_obrazek.pk %}#nahoru"); window.location.assign("{% url 'galerie_soubor' soustredeni=soustredeni.id 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' galerie=galerie.pk soubor=dalsi_obrazek.pk %}#nahoru"); window.location.assign("{% url 'galerie_soubor' soustredeni=soustredeni.id galerie=galerie.pk soubor=dalsi_obrazek.pk %}#nahoru");
} }
{% endif %} {% endif %}
if (e.which == 27) { if (e.which == 27) {
window.location.assign("{% url 'galerie_galerie' galerie=galerie.pk %}#obsah"); window.location.assign("{% url 'galerie_galerie' soustredeni=soustredeni.id galerie=galerie.pk %}#obsah");
} }
}); });
@ -51,7 +51,7 @@
<h2> <h2>
{% for g in cesta %} {% for g in cesta %}
<a href="{% url 'galerie_galerie' galerie=g.pk %}">{{ g.nazev }}</a>{% if not forloop.last %} >{% endif %} <a href="{% url 'galerie_galerie' soustredeni=soustredeni.id galerie=g.pk %}">{{ g.nazev }}</a>{% if not forloop.last %} >{% endif %}
{% endfor %} {% endfor %}
</h2> </h2>
@ -60,7 +60,7 @@
{% 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' galerie=galerie.pk soubor=predchozi_obrazek.pk %}#nahoru"></a> <a title="Předchozí" class="predchozi_obrazek" href="{% url 'galeie_soubor' soustredeni=soustredeni.id galerie=galerie.pk soubor=predchozi_obrazek.pk %}#nahoru"></a>
</div> </div>
{% endwith %} {% endwith %}
{% endif%} {% endif%}
@ -70,7 +70,7 @@
{% 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' galerie=galerie.pk soubor=dalsi_obrazek.pk %}#nahoru"></a> <a title="Další" class="dalsi_obrazek" href="{% url 'galerie_soubor' soustredeni=soustredeni.id galerie=galerie.pk soubor=dalsi_obrazek.pk %}#nahoru"></a>
</div> </div>
{% endwith %} {% endwith %}
{% endif%} {% endif%}
@ -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' galerie=predchozi_galerie.pk soubor=predchozi_galerie.obrazek_set.last.pk %}#nahoru"> Předchozí: <a href="{% url 'galerie_soubor' soustredeni=soustredeni.id 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' galerie=galerie.pk soubor=obrazek.pk %}#nahoru">{% zmenseny_nahled obrazek.jako_bazmek height=100 %}</a> <a href="{% url 'galerie_soubor' soustredeni=soustredeni.id galerie=galerie.pk soubor=obrazek.pk %}#nahoru">{% zmenseny_nahled obrazek.jako_bazmek height=100 %}</a>
{% endfor %} {% endfor %}
{% zmenseny_nahled obrazek.jako_bazmek alt=obrazek.popisek 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' galerie=galerie.pk soubor=obrazek.pk %}#nahoru">{% zmenseny_nahled obrazek.jako_bazmek height=100 %}</a> <a href="{% url 'galerie_soubor' soustredeni=soustredeni.id 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' galerie=nasledujici_galerie.pk soubor=nasledujici_galerie.obrazek_set.first.pk %}#nahoru"> Následující: <a href="{% url 'galerie_soubor' soustredeni=soustredeni.id galerie=nasledujici_galerie.pk soubor=nasledujici_galerie.obrazek_set.first.pk %}#nahoru">
{{nasledujici_galerie}} {{nasledujici_galerie}}
</a> </a>
{% endif %} {% endif %}

View file

@ -18,7 +18,7 @@ Galerie popisekgalerie.nazev}}
<h2> <h2>
{% for g in cesta %} {% for g in cesta %}
{% if not forloop.last %} {% if not forloop.last %}
<a href="{% url 'galerie_galerie galerie=g.pk %}">{{ g.nazev }}</a> > <a href="{% url 'galerie_galerie' galerie=g.pk soustredeni=soustredeni.id %}">{{ g.nazev }}</a> >
{% else %} {% else %}
{{ g.nazev }} {{ g.nazev }}
{% endif %} {% endif %}
@ -39,7 +39,7 @@ Galerie popisekgalerie.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' galerie=g.pk %}">{{ g.nazev }}</a> <a href="{% url 'galerie_galerie' galerie=g.pk soustredeni=soustredeni.id %}">{{ g.nazev }}</a>
{% else %} {% else %}
{{ g.nazev }} {{ g.nazev }}
{% endif %} {% endif %}
@ -51,7 +51,7 @@ Galerie popisekgalerie.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' galerie=pgalerie.pk %}" <a href="{% url 'galerie_galerie' soustredeni=soustredeni.id 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 popisekgalerie.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_doprava' galerie=galerie.pk subgalerie=pgalerie.pk %}">+</a></span> <span class="plus"><a href="{% url 'galerie_doprava' galerie=galerie.pk subgalerie=pgalerie.pk soustredeni=soustredeni.id %}">+</a></span>
<span class="minus"><a href="{% url 'galerie_doleva' galerie=galerie.pk subgalerie=pgalerie.pk %}">-</a></span> <span class="minus"><a href="{% url 'galerie_doleva' galerie=galerie.pk subgalerie=pgalerie.pk soustredeni=soustredeni.id %}">-</a></span>
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
@ -80,7 +80,7 @@ Galerie popisekgalerie.nazev}}
{% if user.je_org %} {% if user.je_org %}
<div class="mam-org-only"> <div class="mam-org-only">
{% if galerie.zobrazit == 1 %} {% if galerie.zobrazit == 1 %}
<a href="{% url 'galerie_nova' galerie=galerie.pk %}">Vytvořit novou podgalerii</a>, <a href="{% url 'admin:galerie_galerie_change' galerie.pk %}">upravit galerii v adminu</a> <a href="{% url 'galerie_nova' galerie=galerie.pk soustredeni=soustredeni.id %}">Vytvořit novou podgalerii</a>, <a href="{% url 'admin:galerie_galerie_change' galerie.pk %}">upravit galerii v adminu</a>
{% else %} {% else %}
Jestli chceš změnit pořadí podgalerií nebo přidat novou, nastav zobrazení jen pro orgy v <a href="{% url 'admin:galerie_galerie_change' galerie.pk %}">adminu</a>. Jestli chceš změnit pořadí podgalerií nebo přidat novou, nastav zobrazení jen pro orgy v <a href="{% url 'admin:galerie_galerie_change' galerie.pk %}">adminu</a>.
{% endif %} {% endif %}
@ -95,7 +95,7 @@ Galerie popisekgalerie.nazev}}
{% if obrazek.popisek %} {% if obrazek.popisek %}
title="{{ obrazek.popisek }}" title="{{ obrazek.popisek }}"
{% endif %} {% endif %}
href="{% url 'galerie_soubor' galerie=galerie.pk soubor=obrazek.pk %}#nahoru" class="galerie_nahled"> href="{% url 'galerie_soubor' soustredeni=soustredeni.id 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.popisek (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 #}
@ -107,12 +107,12 @@ Galerie popisekgalerie.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' galerie=predchozi.pk %}">Předchozí: {{ predchozi.nazev }}</a> <a href="{% url 'galerie_galerie' soustredeni=soustredeni.id 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' galerie=nasledujici.pk %}">Následující: {{ nasledujici.nazev }}</a> <a href="{% url 'galerie_galerie' soustredeni=soustredeni.id galerie=nasledujici.pk %}">Následující: {{ nasledujici.nazev }}</a>
</div> </div>
{% endif %} {% endif %}
</div> </div>

BIN
galerie/testfiles/bila.mp4 Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
galerie/testfiles/metal.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

140
galerie/tests.py Normal file
View file

@ -0,0 +1,140 @@
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase, Client, override_settings
from django.urls import reverse
from galerie.models import Galerie, Soubor
from soustredeni.models import Soustredeni
import django.contrib.auth.models as auth
import personalni.models as pers
import tvorba.models as tv
from contextlib import ExitStack
from pathlib import Path
import shutil
import tempfile
# NOTE: Existují metody, jak si pořídit kontext: https://docs.python.org/3/library/unittest.html#unittest.TestCase.enterClassContext
# Nepoužíváme je, protože jsem nepřišlo na to, jak je pak použít v `@override_settings(MEDIA_ROOT=media_dir)`
# Ref: https://stackoverflow.com/a/2269295
tempdir = tempfile.TemporaryDirectory(prefix='mamweb_test')
media_dir = Path(tempdir.name) / 'media'
class GalerieTests(TestCase):
@classmethod
def setUpTestData(cls):
org_perm = auth.Permission.objects.get(content_type=ContentType.objects.get_for_model(auth.User), codename='org')
resitel_perm = auth.Permission.objects.get(content_type=ContentType.objects.get_for_model(auth.User), codename='resitel')
r = tv.Rocnik.objects.create(rocnik=42, prvni_rok=1970)
cls.sous_a = Soustredeni.objects.create(rocnik=r)
cls.sous_b = Soustredeni.objects.create(rocnik=r)
cls.neucastnik = pers.Resitel.objects.create(osoba=pers.Osoba.objects.create(user=auth.User.objects.create_user(username='ne')))
cls.neucastnik.osoba.user.user_permissions.add(resitel_perm)
cls.ucastnik_a = pers.Resitel.objects.create(osoba=pers.Osoba.objects.create(user=auth.User.objects.create_user(username='ua')))
cls.ucastnik_a.osoba.user.user_permissions.add(resitel_perm)
cls.sous_a.ucastnici.add(cls.ucastnik_a)
cls.ucastnik_b = pers.Resitel.objects.create(osoba=pers.Osoba.objects.create(user=auth.User.objects.create_user(username='ub')))
cls.ucastnik_b.osoba.user.user_permissions.add(resitel_perm)
cls.sous_b.ucastnici.add(cls.ucastnik_b)
cls.org = pers.Organizator.objects.create(osoba=pers.Osoba.objects.create(user=auth.User.objects.create_user(username='o', is_staff=True)))
cls.org.osoba.user.user_permissions.add(org_perm)
def setUp(self):
media_dir.mkdir()
def tearDown(self):
shutil.rmtree(media_dir)
@classmethod
def tearDownClass(cls):
super().tearDownClass()
tempdir.cleanup()
# TODO: tohle není moc unit test. Správnější by bylo mít polopřipravené
# věci (sous s galerií, sous bez galerie, sous se špatně uspořádanými
# galeriemi ap.) a dedikované testy na jednotlivé úkony. Ale teď jsem to
# začalo psát takhle a chci to nejdřív dopsat a commitnout, takže pokud to
# zapomenu rozstřelit na menší, tak to takhle zůstane…
@override_settings(MEDIA_ROOT=media_dir)
def test_vyrobeni_galerii_k_sousu(self):
"""Vyrobí strukturu galerií odpovídající sousové běžné struktuře pomocí příslušných views"""
org_client = Client()
org_client.force_login(self.org.osoba.user)
resp = org_client.get(reverse('galerie_nova', kwargs={'soustredeni': self.sous_a.id, 'galerie': 0}))
self.assertEqual(resp.status_code, 200)
tf = Path(settings.BASE_DIR) / 'galerie' / 'testfiles'
filenames_pa = [
tf / 'kod_emoji.jpg',
tf / 'metal.jpg',
tf / 'ohno_small.jpg',
]
filenames_so = [
tf / 'pf2020_small.jpg',
]
resp = org_client.post(
reverse('galerie_nova', kwargs={'soustredeni': self.sous_a.id, 'galerie': 0}),
data={'nazev': 'Top galerie k sousu A'},
follow=True,
)
self.assertEqual(resp.status_code, 200)
# Teď je kind-of těžké kliknout na „přidat novou podgalerii“, protože ten odkaz je někde v HTML vyrenderovaný templatem.
# Ale můžeme vytáhnout pk galerie z kontextu
top_gal = resp.context['galerie']
self.assertIsInstance(top_gal, Galerie)
# Záměrně vyrobíme nejdřív sobotní a pak páteční galerii, ať je pak můžeme prohodit
with ExitStack() as stack:
files = [stack.enter_context(open(fn, 'rb')) for fn in filenames_so]
resp = org_client.post(
reverse('galerie_nova', kwargs={'soustredeni': self.sous_a.id, 'galerie': top_gal.pk}),
data={'nazev': 'Sobota', 'obr': files},
follow=True,
)
self.assertEqual(resp.status_code, 200)
so_gal = resp.context['galerie']
self.assertIsInstance(so_gal, Galerie)
with ExitStack() as stack:
files = [stack.enter_context(open(fn, 'rb')) for fn in filenames_pa]
resp = org_client.post(
reverse('galerie_nova', kwargs={'soustredeni': self.sous_a.id, 'galerie': top_gal.pk}),
data={'nazev': 'Pátek', 'obr': files},
follow=True,
)
self.assertEqual(resp.status_code, 200)
pa_gal = resp.context['galerie']
self.assertIsInstance(pa_gal, Galerie)
self.assertGreater(pa_gal.poradi, so_gal.poradi)
# Dokonce i tušíme, jaká ta pořadí jsou
# NOTE: pokud tohle začne failovat, tak je asi safe to smazat.
self.assertEqual(pa_gal.poradi, 2)
self.assertEqual(so_gal.poradi, 1)
# Teď je prohodíme:
# NOTE: použití metody PATCH by tady prošlo, protože nekontrolujeme,
# jaká metoda se používá. Ale dokud simulujeme orga na webu s odkazy
# (`<a>`), tak použijeme GET.
resp = org_client.get(
reverse('galerie_doleva', kwargs={'soustredeni': self.sous_a.id, 'galerie': top_gal.pk, 'subgalerie': pa_gal.pk}),
follow=True,
)
self.assertEqual(resp.status_code, 200)
resp = org_client.get(
reverse('galerie_doprava', kwargs={'soustredeni': self.sous_a.id, 'galerie': top_gal.pk, 'subgalerie': so_gal.pk}),
follow=True,
)
self.assertEqual(resp.status_code, 200)
# Změnil se stav
pa_gal.refresh_from_db()
so_gal.refresh_from_db()
self.assertLess(pa_gal.poradi, so_gal.poradi)
self.assertEqual(pa_gal.poradi, 1)
self.assertEqual(so_gal.poradi, 2)

View file

@ -90,6 +90,7 @@ def galerieView(request, soustredeni:int, galerie: int):
'sourozenci': sourozenci, 'sourozenci': sourozenci,
'predchozi': predchozi, 'predchozi': predchozi,
'nasledujici': nasledujici, 'nasledujici': nasledujici,
'soustredeni': soustredeni, # Jen kvůli reverse urls…
'object': galerie, 'object': galerie,
}) })
@ -107,6 +108,9 @@ def souborView(request, soustredeni: int, galerie: int, soubor: int):
# Explicitní pořadí ničemu neuškodí :-) # Explicitní pořadí ničemu neuškodí :-)
soubory = galerie.soubor_set.all().order_by('poradi', 'nazev') soubory = galerie.soubor_set.all().order_by('poradi', 'nazev')
soubory = list(soubory) soubory = list(soubory)
# Pokud někdo umí z DB rovnou vytáhnout příslušnou sadu obrázků, tak to
# bude (teoreticky a asymptoticky) hezčí. Ale pokud neplánujeme mít tisíce
# obrázků v jedné galerii, tak je to asi jedno :-D
index_souboru = soubory.index(soubor) 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_soubory = list(reversed(soubor[:index_souboru])) predchozi_soubory = list(reversed(soubor[:index_souboru]))
@ -172,7 +176,8 @@ def new_galerie(request, galerie: int, soustredeni: int):
# obsluha formulare umoznujiciho multiple nahravani fotek # obsluha formulare umoznujiciho multiple nahravani fotek
if request.method == 'POST': if request.method == 'POST':
form = NewGalerieForm(request.POST, request.FILES) # Tohle je nějaké zbastlené. NewGalerieForm nežere FILES, ručně zpracováváme ``request.FILES.getlist('obr')``. FIXME.
form = NewGalerieForm(request.POST)
if form.is_valid(): if form.is_valid():
# vytvoreni nove galerie # vytvoreni nove galerie
gal = Galerie() gal = Galerie()
@ -187,7 +192,7 @@ def new_galerie(request, galerie: int, soustredeni: int):
else: else:
gal.soustredeni = soustredeni gal.soustredeni = soustredeni
if gal.nadgalerie: if gal.nadgalerie:
gal.poradi = int(len(gal.nadgalerie.galerie_set.all())) + 1 gal.poradi = int(len(gal.nadgalerie.podgalerie.all())) + 1
gal.save() gal.save()
# zpracovani souboru v galerii # zpracovani souboru v galerii
@ -201,7 +206,7 @@ def new_galerie(request, galerie: int, soustredeni: int):
o.save() o.save()
# presmerovani na prave vzniklou galerii # presmerovani na prave vzniklou galerii
return HttpResponseRedirect(reverse('galerie_galerie', kwargs={'galerie': gal.pk})) return HttpResponseRedirect(reverse('galerie_galerie', kwargs={'galerie': gal.pk, 'soustredeni': soustredeni.id}))
else: else:
form = NewGalerieForm() form = NewGalerieForm()
@ -213,22 +218,28 @@ def new_galerie(request, galerie: int, soustredeni: int):
'galerie_text' : galerie_text, 'galerie_text' : galerie_text,
}) })
# FIXME: Tohle by neměly být GETy, ale POSTy/PATCHe, protože mění stav
# (= nejsou safe) a nejsou idempotentní. Ale znamená to mít místo odkazů
# `<button>`y / JS, což se nikomu nechce…
# Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods
def galerie_doprava(request, soustredeni: int, galerie: int, subgalerie: int): def galerie_doprava(request, soustredeni: int, galerie: int, subgalerie: int):
subgalerie: Galerie = get_object_or_404(Galerie, pk=subgalerie) subgalerie: Galerie = get_object_or_404(Galerie, pk=subgalerie)
assert top_galerie(subgalerie).soustredeni.id == soustredeni
assert subgalerie.nadgalerie.pk == galerie assert subgalerie.nadgalerie.pk == galerie
if subgalerie.poradi: if subgalerie.poradi:
subgalerie.poradi += 1 subgalerie.poradi += 1
else: else:
subgalerie.poradi = int(len(subgalerie.nadgalerie.galerie_set.all())) subgalerie.poradi = int(len(subgalerie.nadgalerie.podgalerie.all()))
subgalerie.save() subgalerie.save()
return HttpResponseRedirect(reverse('galerie_galerie', kwargs={'galerie': galerie})) return HttpResponseRedirect(reverse('galerie_galerie', kwargs={'galerie': galerie, 'soustredeni': soustredeni}))
def galerie_doleva(request, soustredeni: int, galerie: int, subgalerie: int): def galerie_doleva(request, soustredeni: int, galerie: int, subgalerie: int):
subgalerie: Galerie = get_object_or_404(Galerie, pk=subgalerie) subgalerie: Galerie = get_object_or_404(Galerie, pk=subgalerie)
assert top_galerie(subgalerie).soustredeni.id == soustredeni
assert subgalerie.nadgalerie.pk == galerie assert subgalerie.nadgalerie.pk == galerie
if subgalerie.poradi: if subgalerie.poradi:
subgalerie.poradi -= 1 subgalerie.poradi -= 1
else: else:
subgalerie.poradi = 1 subgalerie.poradi = 1
subgalerie.save() subgalerie.save()
return HttpResponseRedirect(reverse('galerie_galerie', kwargs={'galerie': galerie})) return HttpResponseRedirect(reverse('galerie_galerie', kwargs={'galerie': galerie, 'soustredeni': soustredeni}))