Jak co nejlépe a obecně na popupy?

28 views
Skip to first unread message

MirekZv

unread,
Feb 26, 2021, 4:25:08 AM2/26/21
to django-cs
Mám ne moc minimalistické, ale pro reálné projekty nutné požadavky na popupy (select+options) ve formulářích:
1. ajaxem získávané options (mimo admin i v něm) - všude a vždy, i když kdyby to umělo automaticky vypnout, když je v modelu méně než např. 100 položek, nevadilo by,
2. dynamický filtr pro options, zejména když jsou relačně závislé popupy (opět mimo admin i v adminu, včetně inlinů); příklad: country & city: jen cities z vybrané country mají být na výběr.

Implementoval jsem toto
včetně funkcionality (2) v inlinech a dokážu to zprovoznit.

Ale je zatím dost individuální práce pro každý případ, lepší by bylo něco generického.
A neřeší to ten ajax.

Je nějaká rozumná cesta, jak dosáhnout (1)+(2) všude v aplikaci?
Které packages přidat do projektu? django-autocomplete-light? a ještě něco?

Díky...
PS: samozřejmě, když jsem šel na Django, tak jsem se domníval, že tam jdu proto, že takovéto věci dělá out-of-the-box. Ach ta moje naivita.

Best regards,
Mirek

MirekZv

unread,
Mar 2, 2021, 5:08:31 AM3/2/21
to django-cs
Nemám na to moc času, zatím mně z toho ale vychází, že, jakkoli mám rád ty stránky simpleisbetterthancomplex, tak tady to je asi ztráta času a krok nesprávným směrem.
A že správně bude použít django-autocomplete-light, který nejspíš přesně všechno toto řeší.

Dne pátek 26. února 2021 v 10:25:08 UTC+1 uživatel MirekZv napsal:

MirekZv

unread,
Mar 3, 2021, 7:22:22 AM3/3/21
to django-cs
Tak jsem si trochu osvěžil paměť.

V Adminu má Django od verze 2.0 autocomplete_fields, což jsou relační pole (ForeignKey, ManyToManyField), které si dohledávají pro svůj widget přes ajax obsah na adrese autocomplete/.
Komunikuje to se .search_fields atributem odkazovaného ModelAdminu, který určuje, ve kterých polích se má vyhledávat to, co uživatel zapíše do popup widgetu. To může být nahrazeno metodou .get_search_results().

Implementace Djanga je slabá (alespoň ve 2.0, ale myslím, že ani později se na to nesáhlo) v tom, že nedokážou rozlišit 2 různé ForeignKey, směřující do stejného modelu. Např. když budete mít v modelu pole "Zadal" a "Schválil", obě směřující do User modelu, nedokážete rozlišit, které právě zadáváte a jak se mají filtrovat dostupné možnosti.
Lze udělat trik s rozšířením Referer adresy (request.headers['Referer']) o např. ?key=..., takže .get_search_results() pak může najít, které ForeignKey po něm požaduje výsledky.
Kdysi jsem si s tím už hrál a v github.com/pyutil/django-admin-autocomplete-all je to implementováno (a trochu popsáno včetně příkladu volání) v autocomplete_all/js/autocomplete_params.js. Spíš snad jako inspirace, protože za zrovna tuto package bych ruku do ohně nedal.

Django 2+ autocomplete_fields ale nepomůžou mimo Admin, takže je opravdu otevřená otázka, jakou cestou jít:
Zda se snažit použít django-autocomplete-light všude a kašlat na Dj2 autocomplete_fields
nebo zda v Adminu upřednostnit zmíněnou nativní vymoženost.

Dne úterý 2. března 2021 v 11:08:31 UTC+1 uživatel MirekZv napsal:

Stanislav Vasko

unread,
Mar 4, 2021, 2:40:19 PM3/4/21
to django-cs
Já bych nebyl až tak kritický. Osobně jsem se tam několikrát inspiroval a přestože některé věci už řeším jinak, dalo mi to možnost mít alespoň nějaké řešení, většinou opravdu simple. Jsem rád za každé srozumitelné návody, zvláště proto, že v češtině prakticky nic uceleného neexistuje. Sice mluvím anglicky plynule, ale učit se nové věci je pro mne příjemnější v češtině. Takto přímé a srozumitelné návody se velice snadno a dobře konzumují a vysloveně nesmysly jsem tam snad nikdy neviděl.

Btw: mátě někdo tip na podobnou stránku, jen pro vyšší level? Většinou na potřebné téma vždy najdu velice pěkné články, ale nic uceleného a mnohahodinová videa na YT mně nikdy nebrala.

Standa
--
--
E-mailová skupina djan...@googlegroups.com
Správa: http://groups.google.cz/group/django-cs
---
Tuto zprávu jste obdrželi, protože jste přihlášeni k odběru skupiny „django-cs“ ve Skupinách Google.
Chcete-li zrušit odběr skupiny a přestat dostávat e‑maily ze skupiny, zašlete e-mail na adresu django-cs+...@googlegroups.com.
Chcete-li tuto diskusi zobrazit na webu, navštivte https://groups.google.com/d/msgid/django-cs/e080bd5f-e7a7-49f3-84cd-3afe0804a958n%40googlegroups.com.

MirekZv

unread,
Mar 5, 2021, 5:43:22 AM3/5/21
to django-cs
@Standa

Jestli je řeč o simpleisbetterthancomplex, tak naprosto souhlas. Super návody. A dokonale popsáno a srozumitelné.

@__all__

Pokud by někdo bojoval s tou variantou použít v adminu django 2+ nativní autocomplete_fields, jsou tam 2 možné problémy:
- některé adminy je vynucováno přidat, protože je v nich vyžadováno search_fields=... ; pokud takové adminy nepotřebujete (máte např. místo nich Inliny), skryjete je takto: has_module_permission = lambda self, req: False
- nelze rozlišit dva ForeignKeys ve stejném modelu směřující také do jediného modelu (o tom už jsem psal) ; řešení lze vzít z django-admin-autocomplete-all (nebo přímo použít tuto knihovnu)

Dne čtvrtek 4. března 2021 v 20:40:19 UTC+1 uživatel stanisl...@gmail.com napsal:

MirekZv

unread,
Mar 12, 2021, 8:57:10 AM3/12/21
to django-cs
Tak s nějakým odstupem jsem si to uzavřel.

django-admin-autocomplete-all jsem dotáhl do podoby, že je snad v Adminu použitelný. Po jeho připnutí podle návodu zobrazí `./manage.py check` informaci, jaké ModelAdmin je potřeba přidat s definovanými get_search_results(). Nepovedlo se mi ale jakkoli to použít mimo Admin.

Takže jsem si udělal závěr, že než to řešit jen v Adminu takto (a vůbec: než tam používat nativní autocomplete_fields), je lepší jít standardní robustní cestou všude stejně, a to je django-autocomplete-light. Data získává přes ajax, filtry nejsou problém (pomocí tzv. forwarded údajů). Naprosto perfektní, čisté řešení, návod, který možná na první pohled trochu zastraší, ale ve skutečnosti je perfektní (ne jako Django samotné, kde návod je taky dokonalý, jen ho pochopíte teprve poté, co jste pochopili problematiku).

Asi to neumí jednu věc, která by se mi ještě líbila pro absolutní dokonalost: Kdyby na backend straně pomocí nějakého .limit(501).count() zjistil, že má <= 500 voleb, mohl by na klienta poslat vše a dále by se filtrovalo už jen na klientu bez zdržování dalšími ajax dotazy. No ale to je detail a to už bych chtěl příliš.
Dne pátek 5. března 2021 v 11:43:22 UTC+1 uživatel MirekZv napsal:
Reply all
Reply to author
Forward
0 new messages