fix: link do PBN na stronie rekordu w instalacji multi-hosted - #761
Conversation
Na stronie rekordu przycisk "Otworz w PBN" prowadzil do adresu "None"
w instalacjach z wiecej niz jedna uczelnia (potwierdzone na nauka.uafm.edu.pl:
`data-open-url=None`).
Przyczyna: szablon wolal `{{ praca.link_do_pbn }}` — Django template nie umie
podac argumentu metodzie, wiec `LinkDoPBNMixin.link_do_pbn()` leciala bez
`uczelnia` i robila fallback na `get_single_uczelnia_or_none()`, ktore przy >1
uczelni zwraca None (celowo — nie ma "uczelni domyslnej"). Metoda zwracala
None, a Django renderowalo to doslownie jako napis "None".
Rozwiazanie analogiczne do istniejacego filtra `link_do_pi` (track 7b) i do
strony autora (FD#390): nowy filtr `link_do_pbn` przekazuje uczelnie
ogladajacego z kontekstu. Gdy uczelni nie da sie ustalic — przycisk nie jest
renderowany zamiast prowadzic donikad.
Dodatkowo `_uczelnia_albo_none()` normalizuje placeholder
`NiezdefiniowanaUczelnia` (klasa bez `pk`, wstawiana przez context processor
gdy host sie nie mapuje) do None — przekazanie go do metody modelu wysypaloby
render na `pbn_api_root`. Uzywa go rowniez `link_do_pi`.
Ten sam wzorzec naprawiony przy okazji w linku do wydawnictwa nadrzednego
z PBN (mial `href="None"`) oraz w legacy `praca_tabela.html`. Ten ostatni ma
pre-existing dlug djlint (ten sam wzorzec `{% if %}<a>{% else %}<a>{% endif %}`
co inne pliki na liscie wyjatkow) — diff nie dodaje nowych bledow (3 przed,
3 po), wiec plik trafia na istniejaca liste exclude.
Testy: repro (multi-homed) + regresja (single-install).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WSUsgzYoDNnXpXGAn5otJg
c8c819d to
df1a718
Compare
Odpowiedź na recenzję (Codex) — wszystkie trzy punkty zaadresowaneGałąź zrebase'owana na Major —
|
links |
wynik |
|---|---|
None (ten cache'owany) |
identyczny |
"normal" |
identyczny |
"cokolwiek" |
identyczny |
"admin" |
zniknęła zbłąkana spacja wewnątrz <a>: <a href="…"> Kowalski Jan</a> → <a href="…">Kowalski Jan</a> |
Kontrakt wszystkich czterech trybów przykryty testem charakteryzującym: src/bpp/tests/test_models/test_opis_bibliograficzny_wariant_autorzy.py (napisany i uruchomiony przed refaktorem, żeby był świadkiem, a nie potwierdzeniem).
Open question — czy praca_tabela.html ma pozostać wspierany?
Tak. dev traktuje go jako żywy wariant: #732 dodał tam oznacz_jezyk (WCAG 3.1.2), dołożył migrację czyszczącą osierocony wiersz dbtemplates i testy test_wcag/test_purge_dbtemplate.py. Dlatego został naprawiony i objęty linterem, a nie wykluczony.
Weryfikacja
1000 passed, 1 skipped—test_views,test_models,test_templatetags,test_wcag,test_opis_bibliograficzny,test_dbtemplates_sync,pbn_api/test_link_do_pi_per_uczelnia,oswiadczenia.pre-commit— wszystkie hooki zielone, bez żadnego nowego wykluczenia.
Poza zakresem (bez zmian)
Ten sam wzorzec bare-call link_do_pbn żyje jeszcze w szablonach admina pbn_api, w importer_publikacji i przemapuj_zrodla_pbn — w multi-hosted pokażą to samo None. Osobny PR.
Znalazłem też przy okazji rzecz starszą niż ten PR i tu nietkniętą: wariant praca_tabela.html nie renderuje się na niezapisanej instancji (denorm woła opis_bibliograficzny() w pre_save, a szablon sięga po praca.streszczenia.exists → ValueError). Do osobnego zgłoszenia.
Problem
Na instalacji UAFM (
nauka.uafm.edu.pl) przycisk „Otwórz w PBN" na stronie rekordu prowadził do adresuNone.Potwierdzone na żywym HTML-u z produkcji, przed jakąkolwiek zmianą:
Dane rekordu są w porządku — PBN UID (
69b414514904f675735a2405) jest poprawny. Problem jest w budowaniu URL-a.Przyczyna źródłowa
praca_tabela_mono.htmlwołał{{ praca.link_do_pbn }}.LinkDoPBNMixin.link_do_pbn()leciała bezuczelnia.get_single_uczelnia_or_none(), które przy więcej niż jednej uczelni zwracaNone— celowo, zgodnie z polityką „nie ma uczelni domyślnej" z audytu multi-hosted.None, a Django renderuje to dosłownie jako tekstNone.Stąd bug widoczny tylko w instalacjach multi-hosted (UAFM), a nie w single-install.
Ta klasa bugów była już łatana punktowo — filtr
link_do_pi(track 7b) oraz strona autora (FD#390) dostały uczelnię z requestu — ale gałąźlink_do_pbnna stronie rekordu została pominięta.Rozwiązanie
link_do_pbnwsrc/bpp/templatetags/prace.py, wzorowany na istniejącymlink_do_pi: przekazuje uczelnię oglądającego z kontekstu szablonu do metody modelu.{% if pbn_url %}wokół przycisku — gdy uczelni nie da się ustalić, przycisk po prostu nie istnieje, zamiast prowadzić donikąd.Nonew Django template jest cichy (nie ma wyjątku), więc guard jest konieczny._uczelnia_albo_none()— context processor wstawia do kontekstu placeholderNiezdefiniowanaUczelnia(klasa bezpk) gdy host się nie mapuje. Przekazanie go do metody modelu wysypałoby render napbn_api_root; helper normalizuje to doNone. Używa go równieżlink_do_pi(ta sama latentna pułapka).Przy okazji ten sam wzorzec naprawiony w linku do wydawnictwa nadrzędnego z PBN (miał
href="None") oraz w legacypraca_tabela.html.Weryfikacja
495 passed, 1 skipped—src/bpp/tests/test_views,test_models/test_struktura,test_safe_tytul,test_autorzy_dla_opisu_skrocony,src/oswiadczenia.pre-commit— wszystkie hooki zielone.Uwagi dla recenzenta
.pre-commit-config.yaml—praca_tabela.htmlma 3 pre-existing błędy djlint (ten sam wzorzec{% if %}<a>{% else %}<a>{% endif %}, który konfiguracja już opisuje jako odroczony tech-debt i który dotyczy 3 innych plików na liście wyjątków). Zmierzone: diff nie dodaje ani jednego nowego błędu (3 przed → 3 po, tylko numer linii przesunięty). Szablon jest legacy — instalowany do dbtemplates migracją 0295, ale żaden widok ani{% include %}go nie używa (strona rekordu renderujepraca_tabela_mono.html). Alternatywą było cofnięcie poprawki w tym pliku.Poza zakresem tego PR-a — ten sam wzorzec bare-call żyje jeszcze w ~10 miejscach, które w multi-hosted pokażą to samo
None:src/pbn_api/templates/admin/*/change_form.html({{ original.link_do_pbn }})src/importer_publikacji/templates/.../step_done.htmlsrc/przemapuj_zrodla_pbn/templates/.../przemapuj_zrodlo.html🤖 Generated with Claude Code
https://claude.ai/code/session_01WSUsgzYoDNnXpXGAn5otJg