EasilyBaffled EasilyBaffled - 1 month ago 13
Python Question

Google App Engine datastore model property returns none

I am trying to create a basic use of the Google App Engine's datastore and db model. My model object is

class Table(db.Model):
row = db.IntegerProperty()
col = db.IntegerProperty()
date = db.DateTimeProperty(auto_now_add=True)


it will be used to just hold a table of rows and columns. User gives input via html, and then I save the table and draw all of the tables in the datastore. I use
Table.all()
to get all tables from the datastore and then try to access their contents so that I can print the table but for some reason when table.row and table.col is read in
for y in range(row):
will apparently return a noneType, does anyone know why?

import webapp2
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
from logging import error

INITIAL_INPUT = """\
<html>
<body>
<form action="/out?%s" method="POST">
<input type="text" name="row" />
<input type="text" name="col" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
"""

class Table(db.Model):
"""Models an individual Guestbook entry with author, content, and date."""
row = db.IntegerProperty()
col = db.IntegerProperty()
date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp2.RequestHandler):
def get(self):
self.response.write(INITIAL_INPUT)

class Out(webapp2.RequestHandler):

def post(self):
newRow = self.request.POST['row']
newCol = self.request.POST['col']
newTable = Table()
newTable.row = int(newRow) if newRow else 1
newTable.col = int(newCol) if newCol else 1
newTable.put()
tables = Table.all()
for table in tables:
self.drawTable(table.row, table.col)


def drawTable(self, row , col):
write = self.response.write
write("<html><body><table>")
for y in range(row):
write("<tr>")
for x in range(col):
cell = "<td bgcolor=\"#00FF00\">" + str(x) + " " + str(y) + "</td>"
if x % 2 == 0:
cell = "<td bgcolor=\"#FF0000\">" + str(x) + " " + str(y) + "</td>"
write(cell)
write("</tr>")
write("</table></body></html>")

application = webapp2.WSGIApplication([
('/', MainPage),
('/out', Out)]
, debug=True)

def main(*args, **kwds):
run_wsgi_app(application)


if __name__ == "__main__":
main()

Answer

Note: the <form action="/out?%s" is incorrect, it only needs to be action="/out".

I'll bet that you have other entities in Table, so your loop picks them up. Use the Datastore Viewer to view By kind: Table and delete the ones with empty row,col values.

Maybe you only want to draw the table that was POSTed? Change these lines:

    tables = Table.all()
    for table in tables:
        self.drawTable(table.row, table.col)

to:

    self.drawTable(newTable.row, newTable.col)