Pylons: Fantamanager parte 4 – update giocatori
<part_3
Vorrei inserire nella pagina “Squadre”, la possibilità di fare l’update del database,
in modo da avere il giocatori e le squadre di appartenenza, sempre aggiornati.
Per prima cosa creo il controller che si occuperà di leggere il file di ingresso per
poi passarlo all’action che aggiornerà il database:
paster controller upload
Inserisco un form nella template ..FantaManagerfantamanagertemplatesderivedseriea.mako:
<%inherit file="/base/base.mako" /> <%def name="title()">Teams</%def> <%def name="heading()"></%def> <%def name="head_tags()"></%def> <p>Squadre Serie A</p> <ul> % for squadra in c.squadre: <li><a href="/team/${squadra}">${squadra}</a></li> % endfor </ul> <%def name="footer()"> <h1>Upgrade Players</h1> ${h.form(h.url(controller='upload', action='upload'), multipart=True)} MCC file: ${h.file('mccfile')} <br /> ${h.submit('submit', 'Upgrade')} ${h.end_form()} </%def>
la parte che mi interessa è:
${h.form(h.url(controller='upload', action='upload'), multipart=True)} MCC file: ${h.file('mccfile')} <br /> ${h.submit('submit', 'Upgrade')} ${h.end_form()}
e sopratutto il context_object h.file(‘mccfile’), che richiamerò nel controller al
momento del “submit”.
Utilizzando parecchi helpers (h.) all’interno del template, è necessario fare le
dovute importazioni, nel modulo FantaManagerfantamanagerlibhelpers:
from webhelpers.html.tags import file from webhelpers.html.tags import stylesheet_link from webhelpers.html.tags import link_to from webhelpers.html import escape, HTML, literal, url_escape from webhelpers.html.tags import * from pylons import url
Ora occupiamoci del controller FantaManagerfantamanagercontrollersupload.py
import logging import fantamanager.lib.helpers as h from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect from fantamanager.model.models import Giocatore from fantamanager.lib.base import BaseController, render from fantamanager.extra.FileBrowser import FileBrowser import fantamanager.model.meta as meta from repoze.what.predicates import not_anonymous, has_permission from repoze.what.plugins.pylonshq import ActionProtector log = logging.getLogger(__name__) class UploadController(BaseController): @ActionProtector(has_permission('admin')) def upload(self): def get_flag_role(idg): """get the role, by idgaz""" if idg < 200: role = 'portiere' elif idg > 200 and idg < 500: role = 'difensore' elif idg > 500 and idg < 800: role = 'ccampista' else: role = 'attaccante' return role mccfile = request.POST['mccfile'] file_in = mccfile.file if file_in != None: file_in.seek(0) for line in file_in.readlines(): val = line.split('|') try: idr = int(val[0]) except ValueError: idr = int(val[0].replace('xefxbbxbf', '')) role = get_flag_role(idr) nomev = val[2].decode('utf-8').replace('"', '') squadrav = val[3].replace('"', '') play_in = meta.Session.query(Giocatore).filter( Giocatore.idgaz == idr).first() if play_in == None: log.info(" <<<< assente giocatore con idgaz = %s" % idr) valore = int(val[27].rstrip()) player = Giocatore() player.idgaz = idr player.nome = nomev player.squadra = squadrav player.valore = valore player.ruolo = role meta.Session.add(player) else: log.info(" ++++ aggiorno giocatore con idgaz = %s" % idr) player = meta.Session.query(Giocatore).filter( Giocatore.idgaz == idr).first() player.idgaz = idr player.nome = nomev player.squadra = squadrav player.valore = int(val[27]) player.ruolo = role meta.Session.commit() file_in.close() log.info("core> dati inseriti con successo") session['flash'] = 'Players successfully updated.' session.save() else: log.info("core> Nessun dato da salvare") redirect(url(controller = 'seriea', action = 'squadre'))
Il context_object (catturata dalla pagina con il codice della template) lo utilizziamo qui:
mccfile = request.POST['mccfile']
poco prima del redirect, abbiamo salvato nella session (un dizionario), alla chiave ‘flash’, il messaggio
che desideriamo far apparire ad update avvenuto (come descritto nel pylons book).
Poi abbiamo salvato la session con il metodo save().
session['flash'] = 'Players successfully updated.' session.save()
Perchè il flash-message funzioni, bisogna innanzitutto importare la session all’interno del controller:
from pylons import session
Poi editiamo la template base, dal quale ereditano tutte le altre template, e modifichiamo il codice:
## -*- coding: utf-8 -*- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>${self.title()}</title> ${self.head()} </head> <h1>Fantacalcio Manager</h1> <body> ${self.header()} ${self.tabs()} ${self.menu()} ${self.heading()} ${self.breadcrumbs()} ${self.flash()} ${next.body()} ${self.footer()} </body> </html> <%def name="title()">Fantacalcio Manager</%def> <%def name="head()">${h.stylesheet_link(h.url('/css/main.css'))}</%def> <%def name="header()"><a name="top"></a></%def> <%def name="tabs()"></%def> <%def name="menu()"></%def> <%def name="heading()"><h1>${c.heading or 'No Title'}</h1></%def> <%def name="breadcrumbs()"></%def> <%def name="footer()"><p><a href="#top">Top ^</a></p></%def> <%def name="flash()"> % if session.has_key('flash'): <div id="flash"><p>${session.get('flash')}</p></div> <% del session['flash'] session.save() %> % endif </%def>
definiamo la funzione flash all’interno della template
${self.flash()}
, subito prima del body, con il seguente codice:
<%def name="flash()"> % if session.has_key('flash'): <div id="flash"><p>${session.get('flash')}</p></div> <% del session['flash'] session.save() %> % endif </%def>
e inseriamo nel file FantaManagerfantamanagerpubliccssmain.css, lo
stile desiderato per l’evidenziazione del nostro flash-message:
#flash { background: #ffc; padding: 5px; border: 1px dotted #000; margin-bottom: 20px; } #flash p { margin: 0px; padding: 0px; }
Ora, quando la action upload (del controller upload), viene chiamata (premendo il pulsante upgrade),
dopo tutte le operazioni effettuate sul file, compreso l’aggiornamento del database,
il messaggio ‘Players successfully updated.’ viene salvato nella session e avviene il redirect alla
template squadre.mako
redirect(url(controller = 'seriea', action = 'squadre'))
Siccome la template squadre.mako eredita da base.mako, prima del viene eseguita la funzione flash.
Tale funzione flash, controlla che nella session sia presente la chiave flash (sì!), ne memorizza il
valore associato alla chiave (in nostro messaggio), cancella la chiave ‘flash’ e salva la
session (per pulirla).
Il messaggio viene quindi visualizzato dalla template figlia (squadre.mako).
Se effettuiamo inoltre un refresh della pagina, il flash-message sparisce, poichè la session
viene ripulita come ultima operazione.
Commenti recenti