简体   繁体   中英

How to display triple nested dictionary values in a Django template?

I have a list of dictionaries produced by a raw django query and a custom sorting algorithm:

ordered_list = [{'qmaLevel': Decimal('1'), 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '12U x 600 x 650 Professional Rack ', 'qmaQuoteAssemblyID': 0, 'qmaPartID': 'RACK S9 ', 'quantity': Decimal('1.00000'), 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '. ', 'qmaQuoteAssemblyID': 1, 'qmaPartID': 'COLOUR ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('3'), 'indent': '________', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': 'Colour: Mannex Suede ', 'qmaQuoteAssemblyID': 21, 'qmaPartID': '800-560192 ', 'quantity': 1.0, 'qmaParentAssemblyID': 1}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '. ', 'qmaQuoteAssemblyID': 2, 'qmaPartID': 'FRAME ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('3'), 'indent': '________', 'materials': {1: {'qmmPartID': '128114 ', 'qmmPartShortDescription': '1.30;300;200;Black/White;Acrylic;Label; ', 'imrWeight': Decimal('0.00000')}, 2: {'qmmPartID': '800-560271 ', 'qmmPartShortDescription': 'Rivet;Alum;Truss;4.0;8.7; ', 'imrWeight': Decimal('0.00149')}, 3: {'qmmPartID': '800-560350 ', 'qmmPartShortDescription': 'Key;Ring;20mm; ', 'imrWeight': Decimal('0.00000')}}, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': 'Label 19" Rack Container Commercial ', 'qmaQuoteAssemblyID': 22, 'qmaPartID': '1A000 ', 'quantity': 1.0, 'qmaParentAssemblyID': 2}, 
{'qmaLevel': Decimal('3'), 'indent': '________', 'materials': {1: {'qmmPartID': '800-560008 ', 'qmmPartShortDescription': 'Colour;Powdercoat;General;Production Use ', 'imrWeight': Decimal('1.00000')}, 2: {'qmmPartID': '124632 ', 'qmmPartShortDescription': '1.90;M2;ZAN; ', 'imrWeight': Decimal('14.91500')}}, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': 'Frame Top x 600 x 650 Typ 0P ', 'qmaQuoteAssemblyID': 23, 'qmaPartID': '0R000P ', 'quantity': 1.0, 'qmaParentAssemblyID': 2}, 
{'qmaLevel': Decimal('3'), 'indent': '________', 'materials': {1: {'qmmPartID': '124632 ', 'qmmPartShortDescription': '1.90;M2;ZAN; ', 'imrWeight': Decimal('14.91500')}, 2: {'qmmPartID': '800-560008 ', 'qmmPartShortDescription': 'Colour;Powdercoat;General;Production Use ', 'imrWeight': Decimal('1.00000')}}, 'qmaQuantityPerParent': Decimal('4.00000'), 'qmaPartShortDescription': 'Frame Vertical 12U H2 Type 1 ', 'qmaQuoteAssemblyID': 24, 'qmaPartID': '0S0221 ', 'quantity': 4.0, 'qmaParentAssemblyID': 2}, 
{'qmaLevel': Decimal('3'), 'indent': '________', 'materials': {1: {'qmmPartID': '800-560008 ', 'qmmPartShortDescription': 'Colour;Powdercoat;General;Production Use ', 'imrWeight': Decimal('1.00000')}, 2: {'qmmPartID': '124632 ', 'qmmPartShortDescription': '1.90;M2;ZAN; ', 'imrWeight': Decimal('14.91500')}}, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': 'Frame Bottom x 600 x 650 Type 0P ', 'qmaQuoteAssemblyID': 25, 'qmaPartID': '0T000P ', 'quantity': 1.0, 'qmaParentAssemblyID': 2}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': {1: {'qmmPartID': '800-560008 ', 'qmmPartShortDescription': 'Colour;Powdercoat;General;Production Use ', 'imrWeight': Decimal('1.00000')}}, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '. ', 'qmaQuoteAssemblyID': 3, 'qmaPartID': 'MOUNTING ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('3'), 'indent': '________', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': 'Base Pro. Levelling Feet + Mount Plate Kit GA ', 'qmaQuoteAssemblyID': 27, 'qmaPartID': '0E220 ', 'quantity': 1.0, 'qmaParentAssemblyID': 3}, 
{'qmaLevel': Decimal('4'), 'indent': '____________', 'materials': {1: {'qmmPartID': '800-560349 ', 'qmmPartShortDescription': 'M10;40;Levelling Foot Adjust Screw; ', 'imrWeight': Decimal('0.03081')}, 2: {'qmmPartID': '800-560268 ', 'qmmPartShortDescription': 'M16;Zinc;Hex;Locknut ', 'imrWeight': Decimal('0.00000')}, 3: {'qmmPartID': '800-560097 ', 'qmmPartShortDescription': 'M05;Zinc;Flange;Nut; ', 'imrWeight': Decimal('0.00164')}, 4: {'qmmPartID': '800-560266 ', 'qmmPartShortDescription': 'M10;Zinc;Hex;CLS8 ', 'imrWeight': Decimal('0.00905')}, 5: {'qmmPartID': '128263 ', 'qmmPartShortDescription': 'M16;M10;M24;Mild;Hex;Threaded;Bush;22mm; ', 'imrWeight': Decimal('0.00000')}, 6: {'qmmPartID': '800-560098 ', 'qmmPartShortDescription': 'M05;15;Steel ', 'imrWeight': Decimal('0.00000')}}, 'qmaQuantityPerParent': Decimal('4.00000'), 'qmaPartShortDescription': 'Levelling Feet ', 'qmaQuoteAssemblyID': 39, 'qmaPartID': '800-250215 ', 'quantity': 4.0, 'qmaParentAssemblyID': 27}, 
{'qmaLevel': Decimal('5'), 'indent': '________________', 'materials': {1: {'qmmPartID': '800-560098 ', 'qmmPartShortDescription': 'M05;15;Steel ', 'imrWeight': Decimal('0.00000')}, 2: {'qmmPartID': '124632 ', 'qmmPartShortDescription': '1.90;M2;ZAN; ', 'imrWeight': Decimal('14.91500')}}, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': ';;;;;Leveling;Foot;Plate; ', 'qmaQuoteAssemblyID': 40, 'qmaPartID': '800-250137 ', 'quantity': 4.0, 'qmaParentAssemblyID': 39}, 
{'qmaLevel': Decimal('3'), 'indent': '________', 'materials': {1: {'qmmPartID': '124887 ', 'qmmPartShortDescription': 'Rivet;Steel;Dome;4.8;1.6-6.4; ', 'imrWeight': Decimal('0.00000')}, 2: {'qmmPartID': '800-560013 ', 'qmmPartShortDescription': 'M06;Nutsert;Open;Large;Flange; ', 'imrWeight': Decimal('0.00000')}, 3: {'qmmPartID': '800-560014 ', 'qmmPartShortDescription': 'M06;16;Zinc;Phillips;Hex;Serrated ', 'imrWeight': Decimal('0.00502')}}, 'qmaQuantityPerParent': Decimal('4.00000'), 'qmaPartShortDescription': 'Gusset Mount Rail 12U x 600 ', 'qmaQuoteAssemblyID': 28, 'qmaPartID': '03020D0 ', 'quantity': 4.0, 'qmaParentAssemblyID': 3}, 
{'qmaLevel': Decimal('4'), 'indent': '____________', 'materials': {1: {'qmmPartID': '124633 ', 'qmmPartShortDescription': '1.50;M2;ZAN; ', 'imrWeight': Decimal('11.77500')}, 2: {'qmmPartID': '800-560008 ', 'qmmPartShortDescription': 'Colour;Powdercoat;General;Production Use ', 'imrWeight': Decimal('1.00000')}}, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': 'Mount Rail Gusset 12U Universal ', 'qmaQuoteAssemblyID': 41, 'qmaPartID': '127040 ', 'quantity': 4.0, 'qmaParentAssemblyID': 28}, 
{'qmaLevel': Decimal('4'), 'indent': '____________', 'materials': {1: {'qmmPartID': '124632 ', 'qmmPartShortDescription': '1.90;M2;ZAN; ', 'imrWeight': Decimal('14.91500')}, 2: {'qmmPartID': '800-560008 ', 'qmmPartShortDescription': 'Colour;Powdercoat;General;Production Use ', 'imrWeight': Decimal('1.00000')}}, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '12U;0600;;;C;Mount;Rail; ', 'qmaQuoteAssemblyID': 42, 'qmaPartID': '127014 ', 'quantity': 4.0, 'qmaParentAssemblyID': 28}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '. ', 'qmaQuoteAssemblyID': 4, 'qmaPartID': 'FRONT DOOR ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('3'), 'indent': '________', 'materials': {1: {'qmmPartID': '800-560008 ', 'qmmPartShortDescription': 'Colour;Powdercoat;General;Production Use ', 'imrWeight': Decimal('1.00000')}}, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': 'No Door Required ', 'qmaQuoteAssemblyID': 29, 'qmaPartID': 'NO DOOR ', 'quantity': 1.0, 'qmaParentAssemblyID': 4}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '. ', 'qmaQuoteAssemblyID': 5, 'qmaPartID': 'REAR DOOR ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('3'), 'indent': '________', 'materials': {1: {'qmmPartID': '800-560008 ', 'qmmPartShortDescription': 'Colour;Powdercoat;General;Production Use ', 'imrWeight': Decimal('1.00000')}}, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': 'No Door Required ', 'qmaQuoteAssemblyID': 34, 'qmaPartID': 'NO DOOR ', 'quantity': 1.0, 'qmaParentAssemblyID': 5}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '(when viewed from front of rack) ', 'qmaQuoteAssemblyID': 6, 'qmaPartID': 'LEFT SIDE PANEL ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '(when viewed from front of rack) ', 'qmaQuoteAssemblyID': 7, 'qmaPartID': 'RIGHT SIDE PANEL ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '. ', 'qmaQuoteAssemblyID': 8, 'qmaPartID': 'ACCESSORIES ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '. ', 'qmaQuoteAssemblyID': 9, 'qmaPartID': 'PDU ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '. ', 'qmaQuoteAssemblyID': 10, 'qmaPartID': 'FRONT VCM ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '. ', 'qmaQuoteAssemblyID': 11, 'qmaPartID': 'REAR VCM ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}, 
{'qmaLevel': Decimal('2'), 'indent': '____', 'materials': None, 'qmaQuantityPerParent': Decimal('1.00000'), 'qmaPartShortDescription': '. ', 'qmaQuoteAssemblyID': 12, 'qmaPartID': 'PACKAGING ', 'quantity': 1.0, 'qmaParentAssemblyID': 0}]

Each dictionary has a nested dictionary called materials and each materials dictionary has some more nested dictionaries with a key qmmQuoteMaterialID which will be 1 to 6 in this example but can have any number from 1 to n depending on the query. Example:

{'qmaLevel': Decimal('4'), 'indent': '____________', 'materials': {1: {'qmmPartID': '800-560349 ', 'qmmPartShortDescription': 'M10;40;Levelling Foot Adjust Screw; ', 'imrWeight': Decimal('0.03081')}, 2: {'qmmPartID': '800-560268 ', 'qmmPartShortDescription': 'M16;Zinc;Hex;Locknut ', 'imrWeight': Decimal('0.00000')}, 3: {'qmmPartID': '800-560097 ', 'qmmPartShortDescription': 'M05;Zinc;Flange;Nut; ', 'imrWeight': Decimal('0.00164')}, 4: {'qmmPartID': '800-560266 ', 'qmmPartShortDescription': 'M10;Zinc;Hex;CLS8 ', 'imrWeight': Decimal('0.00905')}, 5: {'qmmPartID': '128263 ', 'qmmPartShortDescription': 'M16;M10;M24;Mild;Hex;Threaded;Bush;22mm; ', 'imrWeight': Decimal('0.00000')}, 6: {'qmmPartID': '800-560098 ', 'qmmPartShortDescription': 'M05;15;Steel ', 'imrWeight': Decimal('0.00000')}}, 'qmaQuantityPerParent': Decimal('4.00000'), 'qmaPartShortDescription': 'Levelling Feet ', 'qmaQuoteAssemblyID': 39, 'qmaPartID': '800-250215 ', 'quantity': 4.0, 'qmaParentAssemblyID': 27},

I need to display the contents in the qmmQuoteMaterialID dictionary in a Django template but not sure how to go about it. Here is my current template:

{% for qmaQuoteAssemblyID in ordered_list %}
  <tr>
    <td class="text-center text-muted">{{ qmaQuoteAssemblyID.qmaLevel }}</td>
    <td>
      {% autoescape off %}
        <span style="color:white;">{{ qmaQuoteAssemblyID.indent|escape }}</span>
      {% endautoescape %}
      {{ qmaQuoteAssemblyID.qmaPartID }}
    </td>
    <td class="text-center">{{ qmaQuoteAssemblyID.qmaQuoteAssemblyID }}</td>
    <td class="text-center">{{ qmaQuoteAssemblyID.qmaParentAssemblyID }}</td>
    <td>{{ qmaQuoteAssemblyID.qmaPartShortDescription }}</td>
    <td class="text-center">{{ qmaQuoteAssemblyID.qmaQuantityPerParent|floatformat:"2" }}</td>
    <td class="text-center">{{ qmaQuoteAssemblyID.quantity|floatformat:"2"}}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    {% if qmaQuoteAssemblyID.materials != None %}
      {% for qmmQuoteMaterialID in qmaQuoteAssemblyID.materials %}
        <tr>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td>{{ qmmQuoteMaterialID.qmmQuoteMaterialID }}</td>
          <td>{{ qmmQuoteMaterialID.qmmPartID }}</td>
          <td>{{ qmmQuoteMaterialID.qmmPartShortDescription }}</td>
          <td>{{ qmmQuoteMaterialID.imrWeight }}</td>
        </tr>
      {% endfor %}
    {% endif %}
  </tr>
{% endfor %}

At the moment the above template is allocating the correct amount of rows for the parent item however it is not displaying anything as I don't seem to be calling the related data properly.

Okay, it seems you forgot about the minor details of accessing the ordered list. In default without providing any method accessing the dict just simply return the key. What you need to do, iterate its items:

{% if qmaQuoteAssemblyID.materials != None %}
  {% for key, qmmQuoteMaterialID in qmaQuoteAssemblyID.materials.items %}
    <tr>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td>{{ qmmQuoteMaterialID.qmmQuoteMaterialID }}</td>
      <td>{{ qmmQuoteMaterialID.qmmPartID }}</td>
      <td>{{ qmmQuoteMaterialID.qmmPartShortDescription }}</td>
      <td>{{ qmmQuoteMaterialID.imrWeight }}</td>
    </tr>

Here you can read more about the dict data-structure, its method and looping techniques.

https://docs.python.org/3.4/tutorial/datastructures.html#dictionaries https://docs.python.org/3.4/library/stdtypes.html#typesmapping

Django template doesn't seem to be able to use a variable to lookup a dictionary like this. I was able to create that wanted behavior with a custom filter. Read the official doc here

Example:

from django.template.defaulttags import register


@register.filter
def get_item(dictionary, key):
    return dictionary.get(key)

in <your_app_name>/templatetags/<awesome_name>.py

In template:

{% load get_item %}
{% for level1 in my_dict %}
    {{ my_dict|get_item:level1 }}
    {% for level2 in my_dict|get_item:level1 %}
        {{ my_dict|get_item:level1|get_item:level2 }}
    {% endfor %} 
{% endfor %}

I didn't try the level2.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM