Reputation: 175
I have a Django website, and I'm making a call to Etsy's API in order to display products on the website. The data has multiple levels (abbreviated below):
{
"results":[
{
"title":"#020",
"price":"5.99",
"Images":[
{
"url_570xN":"www.example.com/image1.jpg"
}
]
},
{
"title":"#051",
"price":"5.99",
"Images":[
{
"url_570xN":"www.example.com/image2.jpg"
}
]
},
]
}
I can successfully extract data from the results
part (title
, price
) and display it in the template, but I can't figure out how to do the same thing for the Images
part (url_570xN
). I've spent a few hours trying to find the proper syntax, but I've been unsuccessful.
My views.py
:
# Note: The commented lines are the ones giving me problems.
# Removing them yields no errors and displays the info I want,
# minus the images
def products(request):
parsed_data = []
response = requests.get('https://openapi.etsy.com/v2/shops/{SHOP_ID}/listings/active?includes=Images:1:0&api_key={KEY}')
etsy_data = response.json()
etsy_results = etsy_data['results']
# etsy_images = etsy_data['results']['Images']
for results in etsy_results:
result_data = {}
result_data['title'] = results['title']
result_data['price'] = results['price']
# for Images in etsy_images:
# result_data['url_570xN'] = Images['url_570xN']
parsed_data.append(result_data)
return render(request, 'blog/products.html', {'data' : parsed_data})
My products.html
template:
{% for result in data %}
<p>Title: {{result.title}}
Price: {{result.price}}
<img src={{result.url_570xN}} width="200px"></p>
{% endfor %}
And lastly, the error message I get when uncommenting the lines in my views.py
:
TypeError at /products/
list indices must be integers or slices, not str
Any help would be much appreciated. Thanks!
EDIT 1: Here is the complete traceback for what I have above:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/products/
Django Version: 2.2.4
Python Version: 3.7.4
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog.apps.BlogConfig',
'crispy_forms',
'django_summernote']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "/Users/MeganMcCarty/Documents/coding-projects/djangogirls/myvenv/lib/python3.7/site-packages/django/core/handlers/exception.py" in inner
34. response = get_response(request)
File "/Users/MeganMcCarty/Documents/coding-projects/djangogirls/myvenv/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "/Users/MeganMcCarty/Documents/coding-projects/djangogirls/myvenv/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/MeganMcCarty/Documents/coding-projects/djangogirls/blog/views.py" in products
21. etsy_images = etsy_data['results']['Images']
Exception Type: TypeError at /products/
Exception Value: list indices must be integers or slices, not str
EDIT 2:
I changed my views.py
as follows, based on Tom Carrick's answer. Everything works now, thank you so much!
parsed_data = []
response = requests.get('https://openapi.etsy.com/v2/shops/{SHOP_ID}/listings/active?includes=Images:1:0&api_key={KEY}')
etsy_data = response.json()
etsy_results = etsy_data['results']
for results in etsy_results:
result_data = {}
result_data['title'] = results['title']
result_data['price'] = results['price']
result_data['url_570xN'] = results['Images'][0]['url_570xN']
parsed_data.append(result_data)
return render(request, 'blog/products.html', {'data' : parsed_data})
Upvotes: 1
Views: 493
Reputation: 6616
The problem is that the images are not directly under results
, but they are part of each item, at the same level as title
and price
. There can also be multiple images so I'm assuming here you just want the first one for each product.
So instead you want something like:
def products(request):
parsed_data = []
response = requests.get('https://openapi.etsy.com/v2/shops/{SHOP_ID}/listings/active?includes=Images:1:0&api_key={KEY}')
etsy_data = response.json()
etsy_results = etsy_data['results']
for results in etsy_results:
result_data = {}
result_data['title'] = results['title']
result_data['price'] = results['price']
result_data['url_570xN'] = results['Images'][0]['url_570xN']
parsed_data.append(result_data)
return render(request, 'blog/products.html', {'data' : parsed_data})
Upvotes: 2