Reputation: 385
I wrote this Django view method:
def list_all_devices(request):
all_devices_info = []
fields = Devices.objects.all()
for field in fields:
device = Devices.objects.filter(device_id=field.device_id).values()
dev = device[0]
dev['variables'] = Variables.objects.filter(device_id=field.device_id).values()
del dev['device_creation_datetime']
all_devices_info.append(dev)
return HttpResponse(json.dumps(all_devices_info), content_type="application/json")
For some reason the first code doesn't work, but if I do a minor modification like the following, it starts working, I can't figure out why.
def list_all_devices(request):
all_devices_info = []
fields = Devices.objects.all()
for field in fields:
device = Devices.objects.filter(device_id=field.device_id).values()
dev = device[0]
dev['variables'] = [v for v in Variables.objects.filter(device_id=field.device_id).values()]
del dev['device_creation_datetime']
all_devices_info.append(dev)
return HttpResponse(json.dumps(all_devices_info), content_type="application/json")
When I analyze the modifications:
[v for v in Variables.objects.filter(device_id=field.device_id).values()]
and
Variables.objects.filter(device_id=field.device_id).values()
they seem similar, and both seem to be lists and have the same information inside. But when the json.dumps
method is called over it, in the first code it throws the following error on the browser.
Upvotes: 1
Views: 236
Reputation: 10931
Devices.objects.filter(device_id=field.device_id).values() is ValuesQuerySet
which is derived from QuerySet
and both of then are unevaluated
which means that is a query yet is not executed on database until you apply list or iterate on it.
When you use json.dumps
you need data not query.
Apply following to see the types:
Devices.objects.filter(device_id=field.device_id).values().__class__
django.db.models.query.ValuesQuerySet
Devices.objects.filter(device_id=field.device_id).values().__class__.__base__
django.db.models.query.QuerySet
Upvotes: 1
Reputation: 660
values() doesn't return a simple data type.
I tried with a django model:
dir(myModel.objects.all().values())
['and', 'bool', 'class', 'deepcopy', 'delattr', 'dict', 'doc', 'format', 'getattribute', 'getitem', 'getstate', 'hash', 'init', 'iter', 'len', 'module', 'new', 'nonzero', 'or', 'reduce', 'reduce_ex', 'repr', 'setattr', 'setstate', 'sizeof', 'str', 'subclasshook', 'weakref', '_add_hints', '_as_sql', '_base_queryset_class', '_batched_insert', '_clone', '_create_object_from_params', '_db', '_earliest_or_latest', '_extract_model_params', '_fetch_all', '_fields', '_filter_or_exclude', '_for_write', '_has_filters', '_hints', '_insert', '_known_related_objects', '_merge_known_related_objects', '_merge_sanity_check', '_next_is_sticky', '_populate_pk_values', '_prefetch_done', '_prefetch_related_lookups', '_prefetch_related_objects', '_prepare', '_raw_delete', '_result_cache', '_setup_aggregate_query', '_setup_query', '_specialized_queryset_class', '_sticky_filter', '_update', 'aggregate', 'all', 'annotate', 'annotation_names', 'as_manager', 'bulk_create', 'complex_filter', 'count', 'create', 'dates', 'datetimes', 'db', 'defer', 'delete', 'distinct', 'earliest', 'exclude', 'exists', 'extra', 'extra_names', 'field_names', 'filter', 'first', 'get', 'get_or_create', 'in_bulk', 'is_compatible_query_object_type', 'iterator', 'last', 'latest', 'model', 'none', 'only', 'order_by', 'ordered', 'prefetch_related', 'query', 'raw', 'reverse', 'select_for_update', 'select_related', 'update', 'update_or_create', 'using', 'value_annotation', 'values', 'values_list']
And this is the dir for a python array:
dir([])
['add', 'class', 'contains', 'delattr', 'delitem', 'delslice', 'doc', 'eq', 'format', 'ge', 'getattribute', 'getitem', 'getslice', 'gt', 'hash', 'iadd', 'imul', 'init', 'iter', 'le', 'len', 'lt', 'mul', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'reversed', 'rmul', 'setattr', 'setitem', 'setslice', 'sizeof', 'str', 'subclasshook', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
Upvotes: 1