views:

83

answers:

1

Hi,

Im trying to iterate over a nestled dict list. The first level works fine. But the second level is treated like a string not dict.

In my template I have this:

{% for product in Products %}
<li>
    <p>{{ product }}</p>
    {% for partType in product.parts %}
        <p>{{ partType }}</p>
        {% for part in partType %}
            <p>{{ part }}</p>
        {% endfor %}
    {% endfor %}
</li>
{% endfor %}

It's the {{ part }} that just list 1 char at the time based on partType. And it seams that it's treated like a string. I can however via dot notation reach all dict but not with a for loop. The current output looks like this:

    Color    
C    
o    
l    
o    
r    
Style    
S
.....

The Products object looks like this in the log:

[{'product': <models.Products.Product object at 0x1076ac9d0>, 'parts': {u'Color': {'default': u'Red', 'optional': [u'Red', u'Blue']}, u'Style': {'default': u'Nice', 'optional': [u'Nice']}, u'Size': {'default': u'8', 'optional': [u'8', u'8.5']}}}]

What I trying to do is to pair together a dict/list for a product from a number of different SQL queries.

The web handler looks like this:

typeData = Products.ProductPartTypes.all()
    productData = Products.Product.all()
    langCode = 'en'
    productList = []

    for product in productData:
        typeDict = {}
        productDict = {}
        for type in typeData:
            typeDict[type.typeId] = { 'default' : '', 'optional' : [] }

        productDict['product'] = product
        productDict['parts'] = typeDict

        defaultPartsData = Products.ProductParts.gql('WHERE __key__ IN :key', key = product.defaultParts)
        optionalPartsData = Products.ProductParts.gql('WHERE __key__ IN :key', key = product.optionalParts)

        for defaultPart in defaultPartsData:
            label = Products.ProductPartLabels.gql('WHERE __key__ IN :key AND partLangCode = :langCode', key = defaultPart.partLabelList, langCode = langCode).get()
            productDict['parts'][defaultPart.type.typeId]['default'] = label.partLangLabel

        for optionalPart in optionalPartsData:
            label = Products.ProductPartLabels.gql('WHERE __key__ IN :key AND partLangCode = :langCode', key = optionalPart.partLabelList, langCode = langCode).get()
            productDict['parts'][optionalPart.type.typeId]['optional'].append(label.partLangLabel)

        productList.append(productDict)    

    logging.info(productList)
    templateData = { 'Languages' : Settings.Languges.all().order('langCode'), 'ProductPartTypes' : typeData, 'Products' : productList }

I've tried making the dict in a number of different ways. Like first making a list, then a dict, used tulpes anything I could think of.

Any help is welcome!

Bouns: If someone have an other approach to the SQL quires, that is more then welcome. I feel that it kinda stupid to run that amount of quires. What is happening that each product part has a different label base on langCode.

..fredrik

+6  A: 

Iterating over a dict yields the keys. You want either the iteritems() or itervalues() method.

{% for partName, partType in product.parts.iteritems %}
    <p>{{ partName }}</p>
    {% for part in partType %}
        <p>{{ part }}</p>
    {% endfor %}
  ....
Ignacio Vazquez-Abrams
Sweet, thanks. Only thing one might need to know if one uses Google App Engine, you need to set the django version to 1.1. The standard version in GAE is 0.96 and it doesn't support 5 keyword for loops.
fredrik