#35071: Resolve lazy translation objects inside dictionaries when saving 
JSONFields
-------------------------------------+-------------------------------------
               Reporter:  Jacob      |          Owner:  nobody
  Walls                              |
                   Type:  New        |         Status:  new
  feature                            |
              Component:  Database   |        Version:  4.2
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 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
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/35071>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018cb6f77171-d9c8b2d6-a2b6-4b83-9584-7a524db98393-000000%40eu-central-1.amazonses.com.

Reply via email to