Django a Client side routing

62 views
Skip to first unread message

Robert Jonathan Šimon

unread,
Jan 31, 2015, 8:55:42 AM1/31/15
to djan...@googlegroups.com
Dobrý den,
ve svém projektu bych chtěl použít client side routing (použití AJAXu pro úpravu části stránky spolu s URL adresou, ale aby URL adresa fungovala i samostatně). Můžete mi něco doporučit? Už jsem si něco hledal, ale pořád v tom velmi tápu. Měl bych použít Django REST framework+Backbone? Nebo úplně něco jiného? Víte o nějakém velmi dobrém tutorialu?
Předem děkuji za odpověď

Tomáš Ehrlich

unread,
Jan 31, 2015, 9:17:44 AM1/31/15
to djan...@googlegroups.com
Ahoj,
jak by ta adresa měla fungovat samostatně?

Pokud budeš mít view BookList na /books, tak můžeš (např. v AngularJS) udělat, aby po načtení frontendu se při přiknutí na /books/detail/1 načetl pouze detail knížky pomocí AJAXu. Django je v tuto chvíli ze hry, vůbec nic na něj nejde.

Pokud ale příjdeš rovnou na /books/detail/1, tak si musíš vybrat co udělat.
a) Zobrazit samostatné view pro detail — nuda, prostě si v urls.py nadefinuješ view
b) Použít stejné view jako pro seznam, ale na frontendu zobrazit detail — v urls.py musíš mít něco jako /books(/.*)?, a frontend už by si to měl pořešit sám. Doufám. AngularJS to u nás dělá, ale přesný řešení neznám.

Jak to tak po sobě čtu, je to víc frontend řešení, Django z půlky ani není, že se děje něco nekalého.


Tom


31. 1. 2015 v 14:55, Robert Jonathan Šimon <berti...@gmail.com>:

Dobrý den,
ve svém projektu bych chtěl použít client side routing (použití AJAXu pro úpravu části stránky spolu s URL adresou, ale aby URL adresa fungovala i samostatně). Můžete mi něco doporučit? Už jsem si něco hledal, ale pořád v tom velmi tápu. Měl bych použít Django REST framework+Backbone? Nebo úplně něco jiného? Víte o nějakém velmi dobrém tutorialu?
Předem děkuji za odpověď


--
--
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/4eab7203-13e0-4bfa-b73e-e7dded04450d%40googlegroups.com.
Další možnosti najdete na https://groups.google.com/d/optout.

Robert Jonathan Šimon

unread,
Jan 31, 2015, 9:26:51 AM1/31/15
to djan...@googlegroups.com
Myslím to takhle. Jakmile budu na adrese /books/ a uživatel klikne na adresu /books/detail/1/, tak AngularJS/Backbone (nevím co z toho) si přes AJAX načte pouze detail knížky (název, ...), zobrazí ho uživateli a změní URL adresu v prohlížeči na /books/detail/1/ (menu atp. se nepřekreslí). Jakmile uživatel půjde rovnou na adresu /books/detail/1/ (třeba si otevřel novou záložku), tak se mu zobrazí celá stránka včetně záhlaví atp.

Dne sobota 31. ledna 2015 15:17:44 UTC+1 Tomáš Ehrlich napsal(a):

Tomáš Ehrlich

unread,
Jan 31, 2015, 9:53:52 AM1/31/15
to djan...@googlegroups.com
Ta první část je úloha frontendu. S frameworkem neporadím, AngularJS jsem použil jen proto, že je skoro všude a snadněji se mi k tomu hledalo howto.

Ta druhá část je Django a řeší to jednoduchý urlpattern /books/(.*), kdy chceš všechno posílat na tvoji frontend aplikaci a ta zobrazí seznam/detail podle URL (která zároveň nastavuje).

Doporučuju dát API endpoint, který budeš volat přes AJAX někam jinam než na /books/detail/:id, např. /api/books/detail/:id, jinak by to řešení, které jsem popsal, nefungovalo. Ono by to určitě šlo udělat i přes jeden endpoint, ale bylo by to složitější…


Mimochodem, je dobré si i ten seznam knížek dát na API, na url /books si zobrazit pouze frontend aplikaci bez dat a pak to všechno načítat z API. Je trochu problém změnit mindset ze server-side a client-side aplikací, ale jde to.

Tom

31. 1. 2015 v 15:26, Robert Jonathan Šimon <berti...@gmail.com>:

Martin Tiršel

unread,
Jan 31, 2015, 11:04:03 AM1/31/15
to djan...@googlegroups.com
Ahoj

to co hladas, sa nazyva isomorphic application. Zial Django na toto nie je najlepsi nastroj, v tomto vynika Node.js a treba kniznica React.js. Pisat nieco taketo v Djangu znamena pisat velku cast aplikacie dva krat - raz v Pythone a raz v JavaScripte. 

Martin

S pozdravom,
Martin Tiršel,
tel.:
+420 776 790 511 (Vodafone CR)

Tomáš Ehrlich

unread,
Jan 31, 2015, 11:22:06 AM1/31/15
to djan...@googlegroups.com
To není zas taková pravda:

Django (backend) propojuje databázi s http a vrací požadovaná data (ať už vyrenderovaná v HTML nebo surová v JSON) a AngularJS (frontend) tyto data zobrazuje.
Pokud už dopředu víš, jaká view chceš mít s Angularem, tak je v Djangu jednoduše nenapíšeš (pouze render šablony) a vytvoříš si jen API endpoint.

To, že používáš dva jazyky, ještě neznamená, že velkou část musíš psát dvakrát.


A když už, tak kombinujte Haskell a Purescript...

Tom

31. 1. 2015 v 17:04, Martin Tiršel <martin...@gmail.com>:

Martin Tiršel

unread,
Jan 31, 2015, 12:29:31 PM1/31/15
to djan...@googlegroups.com
Mozno som to napisal trocha prehnane (tyka sa to len view casti, nie celej aplikacie), ale skusim to podrobnejsie vysvetlit. Priamym otvorenim URL /books/ v prehliadaci vrati server HTML stranku so zoznamom knih. Priamym otvorenim URL /books/1/ vrati server HTML s detailom knihy. To je klasicke chovanie a to aj ostava. Toto chovanie chce dotazovatel rozsirit tak, aby ked je nacitana HTML stranka so zoznamom knih, tak po kliknuti na detail knihy browser pouzil API a ziskal len samotne data namiesto celej HTML stranky s detailom knihy. Nasledne detail knihy vyrenderuje client side JavaScript z obdrzanych dat.

To znamena, ze je nutne robit rendering server side (pre prve nacitanie danej stranky a robotov) a zaroven client side (pre prechod na danu stranku z inej stranky v klientovi). Teda zvlast sablonu v Djangu, zvlast sablonu pre klientsky JavaScript a trocha toho kodu okolo toho. Vytvorit 2x to iste, udrzovat 2x to iste. V tom je prave u takehoto typu aplikacii vyhoda Node.js, ze jeden a ten isty kod bezi aj na serveri aj na klientovi a toto uz tam maju vyriesene. Ak sa jedna o jednu stranku, tak sa to da prezit, ale ak ma tak fungovat cely web, tak je Node.js na toto vhodnejsie a v Djangu riesit len ciste API.

Martin

S pozdravom,
Martin Tiršel,
tel.:
+420 776 790 511 (Vodafone CR)

Tomáš Ehrlich

unread,
Jan 31, 2015, 12:47:44 PM1/31/15
to djan...@googlegroups.com


31. 1. 2015 v 18:29, Martin Tiršel <martin...@gmail.com>:

Mozno som to napisal trocha prehnane (tyka sa to len view casti, nie celej aplikacie), ale skusim to podrobnejsie vysvetlit. Priamym otvorenim URL /books/ v prehliadaci vrati server HTML stranku so zoznamom knih. Priamym otvorenim URL /books/1/ vrati server HTML s detailom knihy. To je klasicke chovanie a to aj ostava. Toto chovanie chce dotazovatel rozsirit tak, aby ked je nacitana HTML stranka so zoznamom knih, tak po kliknuti na detail knihy browser pouzil API a ziskal len samotne data namiesto celej HTML stranky s detailom knihy. Nasledne detail knihy vyrenderuje client side JavaScript z obdrzanych dat.

Ve chvíli, kdy se rozhodneš, že použiješ nějaký MVC framework, tak opravdu některá view na backendu psát nemusíš, např. /books/1. Jednoduše zobrazíš /books a frontend už si přebere, že má v URL ještě další cestu (/1, tj /:id) a zobrazí ti detail. Jak jsem říkal, detaily neznám, ale *určitě* to tak jde, protože to tak máme na webu.

To znamena, ze je nutne robit rendering server side (pre prve nacitanie danej stranky a robotov) a zaroven client side (pre prechod na danu stranku z inej stranky v klientovi). Teda zvlast sablonu v Djangu, zvlast sablonu pre klientsky JavaScript a trocha toho kodu okolo toho. Vytvorit 2x to iste, udrzovat 2x to iste. V tom je prave u takehoto typu aplikacii vyhoda Node.js, ze jeden a ten isty kod bezi aj na serveri aj na klientovi a toto uz tam maju vyriesene. Ak sa jedna o jednu stranku, tak sa to da prezit, ale ak ma tak fungovat cely web, tak je Node.js na toto vhodnejsie a v Djangu riesit len ciste API.

Ano, s šablonami může být problém, ale části, které generuje Django a které zobrazuje AngularJS máme rozdílné šablony. Pak je pár šablon, které generuje Django a obsahují AngularJS direktivy a s tím taky není problém. Pokud se nějaký objekt zobrazuje na více místech (např. /book/1 v frontend aplikaci a /book/archive/1 jako čistě statické backend view), tak vznikne problém, že jsou dvě šablony, které renderují stejná data. Ale to se nám (naštěstí) stalo jen jednou a vyřešili jsme to responzivní šablonou a iframem.


Proti izomorfním aplikacích fakt nic nemám (pokud je to haskell+purescript :) ), chápu jejich sílu, ale zatím u mě převládají nevýhody nad výhodami a těch problému s Djangem/Angularem zas tak moc není…

Tom

Vojtěch Tranta

unread,
May 19, 2015, 4:42:32 PM5/19/15
to djan...@googlegroups.com
Ahoj Martine!

To, na co jsi narazil je opravdu common problém, který má ovšem sakra hodně řešení.

Tak za A bych řekl, že jde o veliké duplikování kódu, protože pokud chceš opravdu "renderovat" html na frontendu pomocí JS, tak musíš mít stejnou šablonu napsanou ve dvou jazycích tj. django template a nějaký JS (React, angular, handlebars, yourmother.js), což je naprostá kravina, že :)
My to vyřešili tak, že všechno renderuje django a máme xhr middleware, který zjistí, že se vrací ajaxem "snippet", což je kus stránky v JSON (jsou tam třídy a identifikátor, který říká, která část stránky se má přerenderovat) a následně se kus stránky pouze nahradí html kodem, který přijde přes ajax. Na tohle HTML se pak naváží znova javascriptový listenery.

Musím říct, že tohle řešení je asi nejlepší, pokud chceš mít šablony napsané v django template.

Pokud to takhle mít nechceš, tak bych v současné době udělal to, že bych si pustil process v nodu na serveru vedle djanga a donutil django, aby se vykašlalo na renderování svých šablon a ale prostě poslal dotaz na tenhle process v Nodu přes TCP, kde by mu v POSTu poslalo JSON všech context dat, které normálně chodí do šablony a nechal v nodu vykreslit šablonu, která by se django vrátila jako html a django ho pak pošlu do prohlížeče.

Node je javascript, že jo, takže to můžeš mít napsané v Angularové šabloně (nejsem si tim zcela jistej, jeslti to jde) nebo v handlebars.js (to jde určitě) nebo v Reactu (to je celkem kick-ass řešení, přihlédnu-li k tomu, jak to pak sviští na frontendu, protože react pozná, že je html vyrenderované serverem a na clientu pak nic nepřekresluje, jenom se "připne" k vyrenderovanému HTML - tenhle stack používá Abdoc (Source) pro svoje aplikace a weby, docela zajímavé technologie, snoubí eleganci Django - backendu a rychlost a luxus frontendu v Javascriptu, vše přitom server-side rendered)

Dne sobota 31. ledna 2015 18:29:31 UTC+1 Martin Tiršel napsal(a):
Reply all
Reply to author
Forward
0 new messages