﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
35071	Resolve lazy objects inside dictionaries when saving JSONFields	Jacob Walls	Jacob Walls	"I have a model `Notification` like this:

{{{
class Notification(models.Model):
    message = models.TextField(null=True)
    context = models.JSONField(null=True)
}}}

Here is the lazy object...
{{{
>>> from django.utils.translation import gettext_lazy as _
>>> lazy = _(""lazy"")
}}}

... that I can use in a TextField ...

{{{
>>> models.Notification(message=lazy).save()
>>> 
}}}

... but not for the JSONField without string-ifying it myself. Suggesting an implementation that resolves these in one of the methods that prepares values for database insertion. Tested with psycopg2 2.9.9.
{{{
>>> models.Notification(context={'lazy': lazy}).save()
Traceback (most recent call last):
  File ""<console>"", line 1, in <module>
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/django/db/models/base.py"", line 814, in save
    self.save_base(
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/django/db/models/base.py"", line 877, in save_base
    updated = self._save_table(
              ^^^^^^^^^^^^^^^^^
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/django/db/models/base.py"", line 990, in _save_table
    updated = self._do_update(
              ^^^^^^^^^^^^^^^^
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/django/db/models/base.py"", line 1054, in _do_update
    return filtered._update(values) > 0
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/django/db/models/query.py"", line 1231, in _update
    return query.get_compiler(self.db).execute_sql(CURSOR)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/django/db/models/sql/compiler.py"", line 1982, in execute_sql
    cursor = super().execute_sql(result_type)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/django/db/models/sql/compiler.py"", line 1560, in execute_sql
    cursor.execute(sql, params)
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/django/db/backends/utils.py"", line 102, in execute
    return super().execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/django/db/backends/utils.py"", line 67, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/django/db/backends/utils.py"", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/django/db/backends/utils.py"", line 89, in _execute
    return self.cursor.execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/psycopg2/_json.py"", line 78, in getquoted
    s = self.dumps(self.adapted)
        ^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/Users/jwalls/venv311/lib/python3.11/site-packages/psycopg2/_json.py"", line 72, in dumps
    return self._dumps(obj)
           ^^^^^^^^^^^^^^^^
  File ""/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/__init__.py"", line 231, in dumps
    return _default_encoder.encode(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/encoder.py"", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/encoder.py"", line 258, in iterencode
    return _iterencode(o, 0)
           ^^^^^^^^^^^^^^^^^
  File ""/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/encoder.py"", line 180, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type __proxy__ is not JSON serializable
}}}"	New feature	closed	Database layer (models, ORM)	dev	Normal	invalid			Unreviewed	0	0	0	0	0	0
