Atualizando dados no google app engine
-
03-07-2019 - |
Pergunta
Eu estou tentando meu primeiro projeto Google App Engine - banco de dados de um jogador simples estatísticas para uma equipe esportiva estou envolvido com. Dado este modelo:
class Player(db.Model):
""" Represents a player in the club. """
first_name = db.StringProperty()
surname = db.StringProperty()
gender = db.StringProperty()
Eu quero fazer uma interface básica web para criar e modificar jogadores. Minha estrutura de código é algo como isto:
class PlayersPage(webapp.RequestHandler):
def get(self):
# Get all the current players, and store the list.
# We need to store the list so that we can update
# if necessary in post().
self.shown_players = list(Player.all())
# omitted: html-building using django template
Este código produz uma página HTML muito básico composto por um formulário e uma mesa. A tabela tem uma linha para cada jogador, parecendo algo como isto:
<tr>
<td><input type=text name="first_name0" value="Test"></td>
<td><input type=text name="surname0" value="Guy"></td>
<td><select name="gender0">
<option value="Male" selected>Male</option>
<option value="Female" >Female</option>
</select></td>
</tr>
<!-- next row: first_name1, etc. -->
A minha ideia é que eu iria armazenar as instâncias do jogador que eu usei em self.shown_players, para que eu pudesse mais tarde atualizar Jogadores se necessário, em meu método post()
(da mesma classe) fazendo:
def post(self):
# some code skipped
for i, player in enumerate(self.shown_players):
fn = self.request.get('first_name'+str(i)).strip()
sn = self.request.get('surname'+str(i)).strip()
gd = self.request.get('gender'+str(i)).strip()
if any([fn != player.first_name,
sn != player.surname,
gd != player.gender]):
player.first_name = fn
player.surname = sn
player.gender = gd
player.put()
No entanto, isso não funciona porque self.shown_players
não existe quando o método post()
é chamado. Eu acho que o app engine cria uma nova instância da classe cada vez que a página é acessada.
Eu experimentei com a mesma idéia, mas colocando shown_players
no nível de classe ou módulo (e chamando-global
), mas isso não funcionou, por razões que eu não posso divina.
Por exemplo:
shown_players = []
class PlayersPage(webapp.RequestHandler):
def get(self):
# Get all the current players, and store the list.
# We need to store the list so that we can update
# if necessary in post().
global shown_players
shown_players[:] = list(Player.all())
shown_players
parece ter o valor correto dentro get()
porque o HTML gera corretamente, mas é vazio dentro post()
.
O que devo fazer?
Edit: Obrigado, todos. A resposta ( "Just recuperar os jogadores novamente!") Deveria ter sido óbvio :-) Talvez eu vou olhar para memcache um dia, mas eu não estou esperando a lista de jogadores para ir além de 30 no futuro próximo ..
Solução
Em cada pedido que você está trabalhando em uma nova instância da mesma classe. É por isso que você não pode criar um varable em get()
e usar seu valor em post()
. O que você poderia fazer é quer recuperar os valores novamente em sua post()
-método ou armazenar os dados na memcache
.
Consulte a documentação de memcache aqui:
http://code.google.com/ intl / de-dE / appengine / docs / python / memcache /
Outras dicas
No seu método post, pouco antes de o "para" cláusula, recuperar a lista de jogadores a partir de onde ele é armazenado:
def post(self):
# some code skipped
self.shown_players = Player.all().fetch()
for i, player in enumerate(self.shown_players):
...
Eu nunca tentou construir um aplicativo do Google App Engine, mas eu entendo que é um pouco semelhante ao Django nele está lidando de bases de dados etc.
Eu não acho que você deve armazenar coisas em variáveis ??globais e em vez disso deve ser o tratamento de cada transação separadamente. O pedido get funciona porque você está fazendo o que deveria estar fazendo e re-solicitar as informações do banco de dados.
Se você deseja atualizar um jogador em sua função post, você provavelmente vai querer passar nos detalhes, [procurar jogadores com esses detalhes de novo] , modificá-los como quiser. O bit entre parênteses é o passo que está faltando.