S.Jackson
S.Jackson

Reputation: 159

API gives TypeError: unhashable type: 'dict'

I am developing a django-rest-framework API where I do some SQL querying and calculations on a VectorWise database and create a response with get to some input parameters.

I had this structure for my response at first:

    response = {'Date': input_date,
                'Date comparable': date_comparable,
                'CA': {
                    'CA TTC (€)': ca_ttc_n,
                    'Rang magasin': rank,
                    'progression (%)': progression_percentage
                },
                'Nb art / pass caisse': {
                    'nombre': nb_art_pass_caiss,
                    'progression (%)': nb_art_pass_caiss_prog
                },
                'Panier': {
                    '(€)': panier,
                    'progression (%)': prog_panier}
                }

Which worker just fine and gives me back a response.

Then, I tried to improve the code structure and readability of the response like so:

    response = {'Date': input_date,
                'Comparable date': date_comparable,
                'Indicators': {
                    {"Name": "sales",
                     "Value": ca_ttc_n,
                     "Unit": currency,
                     "Rank": rank},
                    {"Name": "sales_progression",
                     "Value": progression_percentage,
                     "Unit": percentage,
                     "Rank": rank},
                    {"Name": "customer_items_number",
                     "Value": nb_art_pass_caiss,
                     "Unit": "Units",
                     "Rank": rank},
                    {"Name": "customer_items_number_progression",
                     "Value": nb_art_pass_caiss_prog,
                     "Unit": percentage,
                     "Rank": rank},
                    {"Name": "basket",
                     "Value": panier,
                     "Unit": currency,
                     "Rank": rank}
                }

This on the other hand keeps throwing errors of TypeError

Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\views\generic\base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\views.py", line 495, in dispatch
    response = self.handle_exception(exc)
  File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\views.py", line 455, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\views.py", line 466, in raise_uncaught_exception
    raise exc
  File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\views.py", line 492, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework_extensions\cache\decorators.py", line 49, in inner
    kwargs=kwargs,
  File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework_extensions\cache\decorators.py", line 68, in process_cache_response
    response = view_method(view_instance, request, *args, **kwargs)
  File "C:\Users\10124077\Projects\dataplatform--web--api\wdc\views.py", line 484, in get
    "Rank": rank}
TypeError: unhashable type: 'dict'

I tried removing the rank field and manupilating a bit to get a better understanding of the issue but I didn't manage to do it as it keeps raising TypeError on other fields of the response body ! Any help ?

Upvotes: 1

Views: 2717

Answers (3)

PaxPrz
PaxPrz

Reputation: 1928

Its cause you are trying to set a dictionary Indicators (with unhashable values like dictionary) without any keys value.

response = {'Date': input_date,
                'Comparable date': date_comparable,
                'Indicators': {
                    'key1':{"Name": "sales",
                     "Value": ca_ttc_n,
                     "Unit": currency,
                     "Rank": rank},
                    'key2':{"Name": "sales_progression",
                     "Value": progression_percentage,
                     "Unit": percentage,
                     "Rank": rank},
                    'key3':{"Name": "customer_items_number",
                     "Value": nb_art_pass_caiss,
                     "Unit": "Units",
                     "Rank": rank},
                    'key4':{"Name": "customer_items_number_progression",
                     "Value": nb_art_pass_caiss_prog,
                     "Unit": percentage,
                     "Rank": rank},
                    'key5':{"Name": "basket",
                     "Value": panier,
                     "Unit": currency,
                     "Rank": rank}
                }
}

else if you do not need keys, make Indicators a list.

Upvotes: 1

ForceBru
ForceBru

Reputation: 44888

The problem is that this:

'Indicators': {
                {"Name": "sales",
                 "Value": ca_ttc_n,
                 "Unit": currency,
                 "Rank": rank},
                {"Name": "sales_progression",
                 "Value": progression_percentage,
                 "Unit": percentage,
                 "Rank": rank},
                {"Name": "customer_items_number",
                 "Value": nb_art_pass_caiss,
                 "Unit": "Units",
                 "Rank": rank},
                {"Name": "customer_items_number_progression",
                 "Value": nb_art_pass_caiss_prog,
                 "Unit": percentage,
                 "Rank": rank},
                {"Name": "basket",
                 "Value": panier,
                 "Unit": currency,
                 "Rank": rank}
            }

...attempts to create a set of dictionaries. So, your code basically does this:

{{"this": "is", "a": "dictionary"}, {"within": "a set"}}

This can't be done because one can construct sets of hashable objects only, and dicts are not hashable. You can read about what "hashable" means in the docs. You could use a list of dictionaries, though:

"Indicators": [
    {'Name': ..., 'Value': ...},
    {'Name': ..., 'Value': ...},
    ...
]

Upvotes: 6

Daniel Roseman
Daniel Roseman

Reputation: 599936

You're missing a list:

            'Indicators': [
                {"Name": "sales",
                 "Value": ca_ttc_n,
                 "Unit": currency,
                 "Rank": rank},
                  ...
              ]
            }

Upvotes: 1

Related Questions