Skip to content

feat(bpp): Szukaj zapytaniem — interaktywny widok DjangoQL poza adminem#223

Merged
mpasternak merged 3 commits into
devfrom
worktree-djangoql-zapytanie
May 13, 2026
Merged

feat(bpp): Szukaj zapytaniem — interaktywny widok DjangoQL poza adminem#223
mpasternak merged 3 commits into
devfrom
worktree-djangoql-zapytanie

Conversation

@mpasternak
Copy link
Copy Markdown
Member

Summary

  • Nowy widok /zapytanie/ dla superuserów i grupy wprowadzanie danych — pełny DjangoQL nad modelami Rekord i Autor poza Django adminem.
  • Autocomplete podpięty pod publiczne endpointy zapytanie/introspect/<model>/ + zapytanie/suggestions/<model>/ (delegacja do djangoql.DjangoQLSchema / SuggestionsAPIView).
  • Popup pozycjonowany u stóp kursora tekstowego (mirror-div + MutationObserver, position: fixed wymuszone bo BPP body ma position:relative + min-height:100vh).
  • TAB-completion (capture-listener zarejestrowany przed DjangoQL.init — kolejność rejestracji w fazie AT_TARGET decyduje).
  • Historia 20 różnych zapytań w localStorage z licznikiem wyników i restore'em po kliknięciu.

UI

  • Badge beta + callout "podgląd technologiczny".
  • Button-group wyboru modelu (CSS-only :has(input:checked)).
  • Pager nad i pod tabelą wyników ({% include _zapytanie_pager.html %}).
  • Reprezentacja rekordu w wynikach: obj.opis_bibliograficzny_cache|safe (kursywy, linki).
  • 13 power-user przykładów dla Rekord + 6 dla Autor z grupowaniem/negacją/in (...).
  • Wpis "zapytaniem" w menu szukaj z ikoną fi-database.

Test plan

  • CI: pytest src/bpp/tests/test_zapytanie.py (14 testów — lokalnie green).
  • CI: pełen suite — nic nie psuje się w testach naokoło.
  • Manualnie: zapytanie tytul_oryginalny ~ "rak" na Rekord — wyniki + opis bibliograficzny z formatowaniem.
  • Manualnie: TAB-completion w pustym textarea — wstawia pierwszą sugestię.
  • Manualnie: przełączenie Rekord ↔ Autor — popup z innym schemą.
  • Manualnie: błąd składni — komunikat zawija się czytelnie.
  • Manualnie: historia zapytań — wpisy po restore, dedup po model+query, "Wyczyść" działa.

🤖 Generated with Claude Code

mpasternak and others added 3 commits May 13, 2026 23:08
…inem

Nowy widok /zapytanie/ (dla superuserow i grupy "wprowadzanie danych")
pozwala przeszukiwac modele Rekord i Autor zapytaniami DjangoQL z
autocompletem, podpowiedziami pozycjonowanymi u stop kursora tekstowego,
historia 20 roznych zapytan w localStorage z restore'em po kliknieciu
oraz paginacja nad i pod tabela wynikow.

Endpointy zapytanie/introspect/<model>/ i zapytanie/suggestions/<model>/
delegacja do djangoql.DjangoQLSchema / SuggestionsAPIView pod tym samym
mixinem uprawnien co main view.

UI: badge "beta" + callout "podglad technologiczny", button-group wyboru
modelu (CSS-only przez :has(input:checked)), monospace textarea,
TAB-completion przez capture-listener zarejestrowany przed DjangoQL.init,
popup repositioning przez mirror-div + MutationObserver (BPP body ma
position:relative+min-height:100vh wiec djangoql default psul layout).

Wpis "zapytaniem" w menu "szukaj" z ikona fi-database.

14 testow pokrywajacych uprawnienia, parsowanie zapytania, rozbicie po
modelach (rekord/autor) i obsluge bledu skladni.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ruff w CI wykryl brak explicit exception chaining przy konwersji
KeyError -> Http404 w _resolve_model_or_404. Pierwotny KeyError nie
wnosi nic do UX — Http404 jest finalnym typem bledu (zly model_key
w URL-u).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…adni

Przyklady zapytan:
- Wyniesione do EXAMPLES w views/zapytanie.py (3 poziomy trudnosci x
  2 modele x 5-10 przykladow). Single source of truth zamiast zahardkodowanych
  list w template.
- Template renderuje przez {% for level in examples %} loop — kazdy <code>
  klikalny, ustawia textarea + przelacza radio modelu.
- Naprawione 3 niepoprawne skladniowo przyklady DjangoQL:
  * not (charakter_formalny.skrot = "AC") -> charakter_formalny.skrot != "AC"
  * not (orcid startswith "0000-") -> orcid not startswith "0000-"
  * not (tytul.skrot in (...)) -> tytul.skrot not in (...)
  DjangoQL grammar nie wspiera unary `not (expr)` — NOT jest tylko modifier
  dla NOT STARTSWITH / NOT ENDSWITH / NOT IN.

Wyniki — nowy layout dla Rekord:
- Kolumny: Reprezentacja | ID | Akcje (ID przeniesione na 2. miejsce).
- ID jako `pk[0]-pk[1]` (np. "12-345") zamiast tuple notation "(12, 345)".
- Caly wiersz klikalny (<tr data-href>), klik na inner <a>/<button> nie
  intercepted.
- Link "Edytuj" do admina prebuildowany w view (ContentType.get_for_id
  cached, NoReverseMatch fallback) — rozkminia content_type_id z pk[0]
  i odsyla do change view konkretnego podtypu (Wydawnictwo_Ciagle, Patent,
  etc).

Testy (44 nowe, 58/58 zielone):
- test_zapytanie_examples_are_valid_djangoql (parametrized, 42 cases) —
  parsuje kazdy przyklad przez DjangoQLParser i fail-uje z dokladnym opisem.
- test_zapytanie_examples_cover_both_models — sanity check.
- test_zapytanie_examples_no_unary_not — regression guard.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mpasternak mpasternak merged commit d055079 into dev May 13, 2026
16 of 17 checks passed
@mpasternak mpasternak deleted the worktree-djangoql-zapytanie branch May 13, 2026 22:15
@mpasternak mpasternak mentioned this pull request May 13, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant