Pylons: Fantamanager parte 2
<part_1
Proviamo ora ad interrogare il database e a fare il render del risultato
di una query, utilizzando un banale template.
Innanzitutto configuriamo il file ..FantaManagerfantamanagerconfigrouting.py
in modo da poter utilizzare degli url dinamici.
# CUSTOM ROUTES HERE
map.connect('/{controller}/{action}') map.connect('/{controller}/{action}/{id}') map.connect('map_giocatori_1', '/team/:team', controller = 'giocatori', action = 'team', team = '[noteam]')
nel terzo map, con la sintassi :variable si assegna a variable, il valore presente
nella url (es. /team/inter -> team = inter)
Con questa mappatura posso usare la stessa regola, per ogni squadra che voglio
renderizzare (vediamo dopo), ma sopratutto serve per passare un argomento alla
action del controller.
Creiamo quindi il controller ‘giocatori’ (già battezzato in routing.py)
paster controller giocatori
Dopo che il controller è stato creato, lo editiamo ed aggiungiamo la action “team”
(anch’essa battezzata in routing.py), che utilizzerò per l’estrapolazione dei dati
e l’import del model Giocatore e della Session con i quali creerò la query:
import logging from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect from fantamanager.lib.base import Session, BaseController, render from fantamanager.model import Giocatore log = logging.getLogger(__name__) class GiocatoriController(BaseController): def __before__(self): self.giocatori_q = Session.query(Giocatore) def index(self): return 'Test: >> Connection OK!' def team(self, team): c.team = team.upper() c.giocatori = [giocatore for giocatore in self.giocatori_q.filter( Giocatore.squadra == c.team).all()] return render('/team.mako')
come si nota, nello skeleton generato da paster, ho aggiunto:
from fantamanager.model import Giocatore from fantamanager.lib.base import Session
il metodo __before__() (viene chiamato subito prima dell’azione, vedere documentazione pylons)
def __before__(self): self.giocatori_q = Session.query(Giocatore)
e la action “team”.
def team(self, team): c.team = team.upper() c.giocatori = [giocatore for giocatore in self.giocatori_q.filter( Giocatore.squadra == c.team).all()] return render('/team.mako')
ecco che al metodo (action) team, viene passato come argomento “team”, che è il
nome della squadra con la quale effettuerò la query e che ho estrapolato con
la url dinamica in routing.py.
team mi serve maiuscolo inquanto i nomi delle squadre nel db, sono maiuscoli.
Dopodichè associo al context_object “c”, la mia variabile e la lista derivata
dalla query, per poter accedervi nella template.
La template ..FantaManagerfantamanagertemplatesteam.mako avrà il seguente contenuto:
<%inherit file="/base.mako" /> <%def name="head_tags()"> <!-- add some head tags here --> </%def> <p>Giocatori ${c.team}</p> <ul> % for giocatore in c.giocatori: <li>${giocatore.nome}</li> % endfor </ul> <a href="${h.url(controller='seriea', action='squadre')}"> back </a>
Creiamo inoltre la template padre ..FantaManagerfantamanagertemplatesbase.mako:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> ${self.head_tags()} </head> <h1>Fantacalcio Manager</h1> <body> ${self.body()} </body> </html>
Avviamo il server per un test:
paster serve --reload development.ini
e visitiamo le seguenti url:
http://127.0.0.1:5000/team/bologna
http://127.0.0.1:5000/team/inter
Ora voglio creare una pagina che mi elenchi tutte le squadre della serie A,
con i link che mi ridirezionino alla pagina relativa alla rosa della squadra
(esempio precedente)
Creo innanzitutto un nuovo controller:
paster controller seriea
Edito e modifico il file ..FantaManagerfantamanagercontrollersseriea.py:
... from sqlalchemy import distinct ... from fantamanager.lib.base import Session, BaseController, render from fantamanager.model import Giocatore ... class SerieaController(BaseController): def __before__(self): self.ateam_q = Session.query(distinct(Giocatore.squadra)) def squadre(self): c.squadre = [team[0] for team in self.ateam_q.all()] return render('/seriea.mako')
Come si nota, il context_object c.squadre sarà disponibile dopo, nella template.
Nota: importanti gli import di distinct e Session (sqlalchemy)
Per accedere alla pagina /seriea/squadre, non importa aggiungere un map.connect nel
file routing.py, inquanto la url risponde già al formato richiesto
map.connect('/{controller}/{action}')
Siccome dalla pagina che elenca le squadre, voglio avere i link alle rose (cioè essere
redirezionato), voglio anche poter ritornare indietro alla pagina di partenza.
Per fare questo utilizzo un helper, richiamabile con “h” all’interno del template, previa
importazione degli helpers, nel file ..FantaManagerfantamanagerlibhelpers.py:
from webhelpers.html import escape, HTML, literal, url_escape from webhelpers.html.tags import * from pylons import url
Nota: attenzione che in pylons < 1.0 l'import è
from routes import url_for
Ecco che posso creare il template seriea.mako con il seguente contenuto:
<%inherit file="/base.mako" /> <%def name="head_tags()"> <!-- add some head tags here --> </%def> <p>Squadre Serie A</p> <ul> % for squadra in c.squadre: <li><a href="/team/${squadra}">${squadra}</a></li> % endfor </ul>
Se ora lanciamo il server e visitiamo la pagina http://127.0.0.1:5000/seriea/squadre
avremo la lista delle squadre con i relativi link, che cliccati porteranno alla pagina
relativa alla rosa. In quest'ultima abbiamo il link che ci riporti alla pagina di partenza.
Commenti recenti