diff options
| author | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-12-03 11:56:22 +0100 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-12-03 11:58:55 +0100 |
| commit | 2c20883cb0df8c56ecbb9a093fc4252410140b59 (patch) | |
| tree | acd8c2527619f1f9a1a6825346f1b78242c5d7ab /django | |
| parent | 306fbf197a742b4b79e4ed23c94f5bbdbec9afdc (diff) | |
[4.0.x] Fixed #33333 -- Fixed setUpTestData() crash with models.BinaryField on PostgreSQL.
This makes models.BinaryField pickleable on PostgreSQL.
Regression in 3cf80d3fcf7446afdde16a2be515c423f720e54d.
Thanks Adam Zimmerman for the report.
Backport of 2c7846d992ca512d36a73f518205015c88ed088c from main.
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/models/base.py | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py index 3c46afcf9f..218782c8df 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -553,6 +553,16 @@ class Model(metaclass=ModelBase): state = self.__dict__.copy() state['_state'] = copy.copy(state['_state']) state['_state'].fields_cache = state['_state'].fields_cache.copy() + # memoryview cannot be pickled, so cast it to bytes and store + # separately. + _memoryview_attrs = [] + for attr, value in state.items(): + if isinstance(value, memoryview): + _memoryview_attrs.append((attr, bytes(value))) + if _memoryview_attrs: + state['_memoryview_attrs'] = _memoryview_attrs + for attr, value in _memoryview_attrs: + state.pop(attr) return state def __setstate__(self, state): @@ -572,6 +582,9 @@ class Model(metaclass=ModelBase): RuntimeWarning, stacklevel=2, ) + if '_memoryview_attrs' in state: + for attr, value in state.pop('_memoryview_attrs'): + state[attr] = memoryview(value) self.__dict__.update(state) def _get_pk_val(self, meta=None): |
