Reputation: 159
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
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
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 dict
s 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
Reputation: 599936
You're missing a list:
'Indicators': [
{"Name": "sales",
"Value": ca_ttc_n,
"Unit": currency,
"Rank": rank},
...
]
}
Upvotes: 1