0

I am using Appengine 1.6.5, accessing a NDB model class property from a jinja2 template I got None, instead I got the right result accessing the same propery on a loop. to explain the problem I post some code

--- Models ---

class Vehicles(ndb.Model):
    registration = ndb.StringProperty()
    brand = ndb.StringProperty()
    model = ndb.StringProperty()
    cost = ndb.FloatProperty()
    km_cost = ndb.FloatProperty()
    viacard = ndb.StringProperty()
    telepass = ndb.StringProperty()

class Employees(ndb.Model):
    user_id = ndb.StringProperty()
    name = ndb.StringProperty()
    surname = ndb.StringProperty()
    email = ndb.StringProperty()
    job = ndb.StringProperty()
    credit_card = ndb.StringProperty()
    cc_expiry_date = ndb.StringProperty()
    vehicle = ndb.KeyProperty(kind=Vehicles)
    last_login = ndb.DateTimeProperty(auto_now=True)
    last_activity = ndb.DateTimeProperty(auto_now=True)

    @property
    def vehicle_registration(self):
        return Key(self.vehicle.kind(),int(self.vehicle.id())).get().registration

--- Handlers --- This i only a part of the handler

class BaseHandler(webapp2.RequestHandler):

    @webapp2.cached_property
    def jinja2(self):
        return jinja2.get_jinja2(app=self.app)

    def render_template(self, filename, **kwargs):
        self.response.write(self.jinja2.render_template(filename, **kwargs))

class EmployeesHandler(BaseHandler):
    @login_required
    def get(self,**kwargs):
        user = users.get_current_user()
        company = models.Company.query().fetch(1)
        employees = models.Employees.query().fetch()
        vehicles = models.Vehicles.query().fetch()

        params = {
            "nickname" : user.nickname(),
            "company" : company,
            "employees" : employees,
            "vehicles" : vehicles
            }
        return self.render_template('employee.html', **params)

--- Template --- This is a part of the templte

<table class="table table-striped table-bordered table-condensed">
  <thead>
    <tr>
      <th>Nome</th>
      <th>Cognome</th>
      <th>Email</th>
      <th>Ruolo</th>
      <th>Carta di credito</th>
      <th>Scadenza</th>
      <th>Auto</th>
      <th>Ultimo accesso</th>
      <th>Ultimo movimento</th>
    </tr>
  </thead>
  <tbody>
    {% for emp in employees %}
    <tr>
      <td>{{ emp.name }}</td>
      <td>{{ emp.surname }}</td>
      <td>{{ emp.email }}</td>
      <td>{{ emp.job }}</td>
      <td>{{ emp.credit_card }}</td>
      <td>{{ emp.cc_expiry_date }}</td>
      <td>({{ emp.vehicle.vehicle_registration }})</td>
      <td>{{ emp.last_login }}</td>
      <td>{{ emp.last_activity }}</td>
    </tr>
    {% endfor %}
  </tbody>
</table>

Can anyone tell me the right way to get the employ's car's registration number? Thank's in advance

Regards, Roberto

Adam Crossland
  • 14,198
  • 3
  • 44
  • 54
rp_189
  • 1
  • 1

1 Answers1

0

try: emp.vehicle.get.vehicle_registration

but, you are running into the n+1 problem and you should really look into prefetching the vehicle reference.

Community
  • 1
  • 1
Shay Erlichmen
  • 31,691
  • 7
  • 68
  • 87
  • I tryed emp.vehicle.get.vehicle_registration, but it don't work – rp_189 Jun 15 '12 at 09:59
  • @rp_189 still getting None?, try printing only emp.vehicle – Shay Erlichmen Jun 15 '12 at 11:06
  • As Shay says, emp.vehicle.get.vehicle_registration should work if emp.vehicle is not None. There is an inconsistency between your code and your template though; the vehicle_registration is on Employee, so you should be trying emp.vehicle_registration (if your code hasn't changed). However I don't see why you are using Key(self.vehicle.kind(),int(self.vehicle.id())).get().registration; you should just be able to use self.vehicle.get().registration. – Guido van Rossum Jun 15 '12 at 22:50
  • @shay-erlichmen if I put emp.vehicle on the template, i got the Key – rp_189 Jun 19 '12 at 13:52
  • @GuidovanRossum emp.vehicle is not None, I did not use self.vehicle.get().registration because it does not work. Your documentation about NDB is clear but I can't solve the problem. If I access emp.vehicle_registration from the handler I got the value, but on the template it do not work. – rp_189 Jun 19 '12 at 13:55
  • @rp_189 does the entity that the key is pointing at still exists or maybe its been deleted somehow? – Shay Erlichmen Jun 19 '12 at 13:58
  • @GuidovanRossum if I use self.vehicle.get().registration it gave me the error AttributeError: 'NoneType' object has no attribute 'registration' – rp_189 Jun 19 '12 at 14:35
  • @rp_189 this means that the key is pointing to a "dead" object – Shay Erlichmen Jun 19 '12 at 14:52
  • @ShayErlichmen I rewrote some stuff and now it work using emp.vehicle_registration, but on the model property the lonly way is to use the formula Key(self.vehicle.kind(),int(self.vehicle.id())).get().registration thankyou – rp_189 Jun 19 '12 at 15:25
  • What is the type of self.vehicle? Is it a Key? It almost looks as if you somehow have created an invalid key using id *string* id where the real key uses an *int* id. E.g. you wrote Key('Model', '42') but you should have written Key('Model', 42) -- note lack of quotes around 42. (This would be in the code that created self.vehicle, who knows how much earlier.) – Guido van Rossum Jun 19 '12 at 15:40
  • @GuidovanRossum thank you so much, I solved. The problem was the id as string instead of int. – rp_189 Jun 19 '12 at 17:31