Podívejte se na všechny díly seriálu nebo na zdrojáky příkladu.
Zase se podíváme na traversal. Zkusíme si do našeho schématu URL zamontovat pager a filtr. Všímám si, že se trošku vzdaluju původnímu tématu – formalchemy. Dnes se ho aspoň trochu dotkneme, právě v tom filtrování.
Nejprve si vymyslíme schéma url. Minule jsme měli root, pod ním jméno modelu, a pak už ten konkrétní záznam, dosažený přes primární klíč:
Přičemž pagerdata i filterdata nechám nepovinná, a když nebudou, nemusí tam být ani ty pomlčky. Tak teď prosím:
# nezapomeňte git pull cd step10 python setup.py develop pserve --reload development.ini
Abychom mohli vyzkoušet pager, tak potřebujeme pár stránek dat. Když navštívíte http://localhost:6543/admin1, tak se Vám do tabulky person uloží 100 záznamů. Teď, pokud to někdo vůbec čte a zajímá ho to, tak mám cvičení: Upravte kód tak, aby z této akce přesměrovalo na výpis položek z tabulky person.
Pager je banální. pagerdata budou číslo stránky-počet položek na stránce. Parsování je v model/resources.py:ModelContext.__init__. Zajímavé je v get_grid, kde si sestavíme v SQLAlchemy dotaz, a pak voláme q[start:end], což zavolá vpodstatě select s limit a offset. Má to jeden problém. Pozná někdo jaký?
V templates/list.mako pak zobrazuji ten pager, poměrně tupým způsobem. V reálné aplikaci bych to dělal trochu zapouzdřeněji. Také neznáme počet stránek, tím se zde nebudu zabývat (pokud si o to někdo v komentářích neřekne). Ještě se podívejte na způsob, jakým je řešeno další/předchozí. Pro kontext modelu máme views pojmenovaná prev a next, která samozřejmě dostanou ten kontext aktuální stránky. V těchto view prostě manipulujeme s číslem první stránky – vlastně upravíme aktuální kontext (který je platný jen v rámci právě zpracovávaného requestu), a pak na něj přesměrujeme.
filterdata by měla být sekvence dvojic klíč=hodnota, urlencoded. Rozhodl jsem se nekomplikovat to, vlastní fitrování udělat tak, že zařadím výsledky, které v příslušném sloupci začínají danou hodnotou. model/resources.py:ModelContext.get_grid. Mnohem zajímavější je ale otázka, jak udělat ten formulář na filtr. Tady nás snad všechny napadne, že k tomu prostě musíme použít formalchemy, když už ho máme. Jenže formalchemy tam strčí i vztažené tabulky, a pokud je sloupec netextového typu (číslo, datum), tak tam dá speciální editovací pole. Já tady pracuju s hodně velkým zjednodušením – pro všechno používám textové pole (bez omezení délky nebo obsahu). V model/tools.py definuju QFieldSet, ve kterém zakážu relations, a o všech polích prohlásím, že je to text. Jako druhou věc, definuju vlastní renderer pro textové pole, který nikdy neomezuje délku, a který se nepokouší najít nějakou default hodnotu. Formulář pro vlastní filtr pak dostaneme z ModelContext.get_q_fs, kterému předhodíme naše filterdata. Vygeneruje nám formulář, který zpracujeme v views/views.py:list_filter, kde zase upravíme aktuální kontext, a přesměrujeme.
Takováhle struktura aplikace má jednu výhodu. To filtrování a ten paging vydrží. Když vyvolám mazání, tak se z něj vrátím na původní výpis (samozřejmě bez toho smazaného záznamu). Stejně tak s editací. Kdybych měl extra akci k prohlížení detailů o položce (což bych ve skutečné aplikaci měl), tak by to taky fungovalo. Prostě, teď jsem na konkrétní stránce, k konrétním filtru, a tam taky zůstanu. Nepotřebuju k tomu session, nemanipuluju s query stringem. S generováním URL mi pomáhá framework.
Jmenuju se Petr Blahoš. Programuju něco přes 20 let. Tady se snažím psát hlavně o Pythonu, webovém frameworku Pyramid, a občas i o něčem úplně jiném.
Přečteno 19 226×
Přečteno 11 853×
Přečteno 9 346×
Přečteno 8 804×
Přečteno 8 594×