James
James

Reputation: 91

Python / Django - Issue with parsing JSON on server

I have a Django server API which is hosted on PythonAnywhere, and a client.py file that is hosted locally on my computer.

The theory of the program is that it will check stock of a particular item, of which the database is accessed via the API.

The client.py file is run and asks for the user input for the product (E.g. "Apple"). This should then be sent in a JSON payload to the server using a "requests.get" request. The server should then load this payload, and parse the information from it, before using the value to query the database. Once it is retrieved as a JSON using the GET function in the client.py, the JSON should be displayed.

However, my issue is that I cannot seem to get my server working. I always get the following issue:

TypeError at api/checkstock: string indices must be integers

I have read up on this, and tried applying various answers to try and fix it, but none seem to work.

Here is the body of my code:

client.py (stored locally)

import json
import requests


def main():
    item_input = input("Enter Item Name:")

    params = {'item': item}

    r = requests.get('http://XXXXX.pythonanywhere.com/api/checkstock/', json=params) # blocked out exact link to avoid fake requests

    print(r.json)

if __name__ == "__main__":
    main()

views.py (hosted on the PythonAnywhere server)

from django.http import HttpResponse
from stock_app.models import Stock
import json

def CheckStock (request):

headers = request.META
content_type = headers['CONTENT_TYPE']

payload = request.body.decode('utf-8')
json_data = json.dumps(payload)

selection = json_data["item"] ## THIS IS WHERE THE ISSUE OCCURS

item_query = Stock.objects.all().filter(item = item).values('item','quantity','expiry_date','description')

the_list = []

for entry in item_query:
    result = {'item':record['item'],'quantity':record['quantity'],'expiry_date':record['expiry_date'],'description':record['description']}
    the_list.append(result)

payload = {'search_results': the_list}

http_response = HttpResponse(json.dumps(payload))
http_response['Content-Type'] = 'application/json'
http_response.status_code = 200
http_response.reason_phrase = 'OK'
return http_response

It's also important to note that everything else is working fine (i.e. the route for the view is set up in urls.py).

Can anyone recommend on how to fix this error? Also, it's important that both the client.py sends the information as a JSON payload, and the views.py returns the information to the client as a JSON payload.

Thanks in advance!


Full Traceback

Traceback:

File "/home/XXXXXX/.virtualenvs/virtualenv/lib/python3.4/site-packages/django/core/handlers/exception.py" in inner
  35.             response = get_response(request)

File "/home/XXXXXX/.virtualenvs/virtualenv/lib/python3.4/site-packages/django/core/handlers/base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "/home/XXXXXX/.virtualenvs/virtualenv/lib/python3.4/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/XXXXXX/.virtualenvs/virtualenv/lib/python3.4/site-packages/django/views/decorators/csrf.py" in wrapped_view
  54.         return view_func(*args, **kwargs)

File "/home/XXXXXX/stock_app/views.py" in CheckStock
  29.         selection = json_data["item"]

Exception Type: TypeError at /api/checkstock/
Exception Value: string indices must be integers

Upvotes: 1

Views: 62

Answers (1)

Alasdair
Alasdair

Reputation: 308869

You should use loads instead of dumps on the server, to convert the json string back into a python dict.

payload = request.body.decode('utf-8')
json_data = json.loads(payload)
selection = json_data["item"]

Upvotes: 4

Related Questions