views:

90

answers:

2

Recently I've spotted a very disturbing issue.

I've got the following python code:

for cat in cats:
  cat.pages = ['apple', 'table', 'computer']

template_values = {
  'cats': cats
}

path = os.path.join(os.path.dirname(__file__), 'templates/index.html')
self.response.out.write(template.render(path, template_values))

The index.html django template looks like this:

{% for cat in cats %}
   <div>{{ forloop.counter }}</div>
   <div>name: {{ cat.cat_name }}</div>
   <div>pages: {{ cat.pages|length }}<br>
{% endfor %}

When I'm running the code above locally with the GAE SDK, I've got the following example results:

1.
name: sample1
pages: 3

2.
name: sample2
pages: 3

etc. I can even build a nested loop since I can access cat.pages inside the loop. However, when I upload this code to the AppEngine, I'll get the following results:

1.
name: sample1
pages: 0

2.
name: sample2
pages: 0

And I can't even access the cat.pages variable at all. What's wrong with my code? Or is this a bug? It works locally as it's expected, but produces this strange result after deploying to GAE servers. Any help is appreciated.

+1  A: 

I think we're going to need more context to see what the problem is here. Where does 'cats' come from, and what are the individual cat objects? I'm guessing they're Model instances, but it's hard to say based on your example. Does it work if you replace them with an array of simple Object subclasses? This would show you if it's something specific to the class you're using.

In general, though, it's a bad idea to assign arbitrary properties to your objects for templating convenience. You'd be better off creating a container object, or dictionary.

Nick Johnson
'cats' was a db.Model - I've realized I can't pass it to Django as it is, so I rebuilt it into nested dictionary inside a python list then I was able to pass it to Django. However it worked well locally using db.Models only that's why I found this problem confusing. Thanks for the help, and you've right it's a bad idea to assign arbitrary properties!
Tamas Kalman
You can pass Model objects to Django templates just fine - just don't try and add properties to them! :)
Nick Johnson
+1  A: 

Maybe try:

for cat in cats:
   for item in ['apple', 'table', 'computer']:
       cat.pages.append(item)

If cat.pages is something funky in GAE like an instrumented list, your original code would have replaced it wholesale with a run-of-the-mill python list.

EoghanM
Tamas Kalman