jinja2 fastapi, output dict to html not showing results

i am trying to pass my searched result to a html page with jinja2 from fastapi.

here is my back end

@app.get("/api/search")
async def get_card_price(request: Request, card_search_keyword: str):
    card_results = await get_card_price(card_search_keyword)
    return templates.TemplateResponse("results.html", {"request": request,
                                                       "card": card_results["card"],
                                                       "card2": card_results["card2"]})

and here is my sample data return

{
  "total_card2": 5,
  "total_card: 3,
  "card2": {
    "98275-JP": {
      "card_condition": "NM",
      "card_price": "¥ 6,500",
      "card_qty": "26",
      "other_condition": {}
    },
    "98709-JP": {
      "card_condition": "NM",
      "card_price": "¥ 6,500",
      "card_qty": "1",
      "other_condition": {}
    }
  },
  "card": {
    "LzgZK": {
      "card_name": "test2",
      "price_updated_date": "2022-01-20T09:05:16.314Z",
      "set_tag": "mh2",
      "rarity": "rare",
      "price_normal": 47.99,
      "price_foil": 99.99
    },
    "LKGxd": {
      "card_name": "test3,
      "price_updated_date": "2022-01-20T09:05:16.314Z",
      "set_tag": "mh2",
      "rarity": "rare",
      "price_normal": 49.99,
      "price_foil": 89.99
    },
    "k93K0": {
      "card_name": "test4",
      "price_updated_date": "2022-01-20T09:05:16.314Z",
      "set_tag": "pmh2",
      "rarity": "rare",
      "price_normal": null,
      "price_foil": 89.99
    }
  }
}

here is my sample html output trying to output card only section but not cards2 dict

{% for cards in card %}
                <div class="row gx-4 gx-lg-5 align-items-center">
                    <div class="col-md-3"><img class="card-img-top mb-5 mb-md-0" src='{{ cards["card_img_id"] }}' alt="..." /></div>
                    <div class="col-md-9">
                        <div class="small mb-1">{{ cards.card_name }}</div>
                        <h1 class="display-5 fw-bolder">{{ cards.card_name }}</h1>
                        <div class="fs-5 mb-5">
                            <span class="text-decoration-line-through">$45.00</span>
                            <span>$40.00</span>
                        </div>
                        <p class="lead">Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium at dolorem quidem modi. Nam sequi consequatur obcaecati excepturi alias magni, accusamus eius blanditiis delectus ipsam minima ea iste laborum vero?</p>
                        <div class="d-flex">
                            <input class="form-control text-center me-3" id="inputQuantity" type="num" value="1" style="max-width: 3rem" />
                            <button class="btn btn-outline-dark flex-shrink-0" type="button">
                                <i class="bi-cart-fill me-1"></i>
                                Add to cart
                            </button>
                        </div>
                    </div>
                </div>
                 <br /><br /><br /> <br /><br /><br />
                 {% endfor %}

i can get 3 results from the loop but outputing from each of the card name and id is not shown out. i am not sure what did i do wrong here this time.


Solution 1:

Make sure you use the same name when assigning the cards to the TemplateResponse as when you access it in the template (use cards in both places).

Since you're using a dict, you're going to get the key of the element when iterating over it with for, not the value.

You can get all the values from the dict by iterating over the dictionary's values instead:

{% for card in cards.values() %}

Another option if you need both the key and the value is to iterate over items:

{% for key, card in cards.items() %}