diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 44c687ffa7..219485750f 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -153,6 +153,11 @@ class BaseExpression: if output_field is not None: self.output_field = output_field + def __getstate__(self): + state = self.__dict__.copy() + state.pop('convert_value', None) + return state + def get_db_converters(self, connection): return ( [] diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index b57a16c35f..d1e622a2d4 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -1,4 +1,5 @@ import datetime +import pickle import unittest import uuid from copy import deepcopy @@ -585,6 +586,11 @@ class BasicExpressionsTests(TestCase): outer = Company.objects.filter(pk__in=Subquery(inner.values('pk'))) self.assertEqual(outer.get().name, 'Test GmbH') + def test_pickle_expression(self): + expr = Value(1, output_field=models.IntegerField()) + expr.convert_value # populate cached property + self.assertEqual(pickle.loads(pickle.dumps(expr)), expr) + class IterableLookupInnerExpressionsTests(TestCase): @classmethod