Django get TypeError: the JSON object must be str, bytes or bytearray, not dict

1.6k views Asked by At

I'm saving a dict into a JSONfield field in my model. This is going ok, but when I want to retrieve data by id, the next error message appears:

***TypeError: the JSON object must be str, bytes or bytearray, not dict

This is an example of what I'm doing:

data = {"123": {"dummy": false, "dummy2": 123}}}

data is saved succesfully with object.save() into the model. I can see that in the database.

When I try to retrieve a registry by id with:

try:
    my_record = models.MyModel.objects.get(business_id=my_id)
except models.MyModel.DoesNotExist:
    logger.debug(f"Record does not exists {my_id}")
    continue

Note: business_id is just a CharField. I think that field is unique, but I'm not sure.

business_id = models.CharField(unique=True, max_length=100)

This is the full Traceback:

    my_record = models.MyModel.objects.get(business_id=my_id)
  File "/home/esufan/repos/verdata-service/venv/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/esufan/repos/verdata-service/venv/lib/python3.8/site-packages/django/db/models/query.py", line 425, in get
    num = len(clone)
  File "/home/esufan/repos/verdata-service/venv/lib/python3.8/site-packages/django/db/models/query.py", line 269, in __len__
    self._fetch_all()
  File "/home/esufan/repos/verdata-service/venv/lib/python3.8/site-packages/django/db/models/query.py", line 1308, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/home/esufan/repos/verdata-service/venv/lib/python3.8/site-packages/django/db/models/query.py", line 70, in __iter__
    for row in compiler.results_iter(results):
  File "/home/esufan/repos/verdata-service/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1100, in apply_converters
    value = converter(value, expression, connection)
  File "/home/esufan/repos/verdata-service/venv/lib/python3.8/site-packages/django/db/models/fields/json.py", line 74, in from_db_value
    return json.loads(value, cls=self.decoder)
  File "/usr/lib/python3.8/json/__init__.py", line 341, in loads
    raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not dict

I know the issue is related to the JSONField because if I delete that field, I can retrieve the object properly (of course that field is Null)

I was reading the Django documentation and I think I need to use filter instead of get, but I'm not sure. I want to execute a get because I want to check if the registry exists in the database, if it exits, I need to update the data, if not I don't need to do anything.

I have 2 options: to save that dict in a different way, or to retrieve the data in a different way. Any thoughts?

1

There are 1 answers

0
Tititun On

If you want to retrieve your saved dictionary as dictionary, create your custom json field:

class CustomJsonField(models.JSONField):
    def from_db_value(self, value, expression, connection):
        if isinstance(value, dict):
            return value
        return super().from_db_value(value, expression, connection)

and then use this field in your model.