Loading django/db/models/base.py +2 −0 Original line number Diff line number Diff line Loading @@ -1459,6 +1459,8 @@ def model_unpickle(model_id, attrs, factory): Used to unpickle Model subclasses with deferred fields. """ if isinstance(model_id, tuple): if not apps.ready: apps.populate(settings.INSTALLED_APPS) model = apps.get_model(*model_id) else: # Backwards compat - the model was cached directly in earlier versions. Loading docs/releases/1.7.2.txt +4 −0 Original line number Diff line number Diff line Loading @@ -151,3 +151,7 @@ Bugfixes (:ticket:`23975`). * Made admin system checks run for custom ``AdminSite``\s (:ticket:`23497`). * Ensured the app registry is fully populated when unpickling models. When an external script (like a queueing infrastructure) reloads pickled models, it could crash with an ``AppRegistryNotReady`` exception (:ticket:`24007`). tests/model_regress/tests.py +35 −0 Original line number Diff line number Diff line Loading @@ -2,7 +2,10 @@ from __future__ import unicode_literals import datetime from operator import attrgetter import pickle import subprocess import sys import tempfile import unittest from django.core.exceptions import ValidationError Loading Loading @@ -245,3 +248,35 @@ class EvaluateMethodTest(TestCase): dept = Department.objects.create(pk=1, name='abc') dept.evaluate = 'abc' Worker.objects.filter(department=dept) class ModelPickleTestCase(TestCase): def test_unpickling_when_appregistrynotready(self): """ #24007 -- Verifies that a pickled model can be unpickled without having to manually setup the apps registry beforehand. """ script_template = """#!/usr/bin/env python import pickle from django.conf import settings data = %r settings.configure(DEBUG=False, INSTALLED_APPS=('model_regress',), SECRET_KEY = "blah") article = pickle.loads(data) print(article.headline)""" a = Article.objects.create( headline="Some object", pub_date=datetime.datetime.now(), article_text="This is an article", ) with tempfile.NamedTemporaryFile(mode='w+', suffix=".py", dir='.', delete=True) as script: script.write(script_template % pickle.dumps(a)) script.flush() try: result = subprocess.check_output(['python', script.name]) except subprocess.CalledProcessError: self.fail("Unable to reload model pickled data") self.assertEqual(result.strip().decode(), "Some object") Loading
django/db/models/base.py +2 −0 Original line number Diff line number Diff line Loading @@ -1459,6 +1459,8 @@ def model_unpickle(model_id, attrs, factory): Used to unpickle Model subclasses with deferred fields. """ if isinstance(model_id, tuple): if not apps.ready: apps.populate(settings.INSTALLED_APPS) model = apps.get_model(*model_id) else: # Backwards compat - the model was cached directly in earlier versions. Loading
docs/releases/1.7.2.txt +4 −0 Original line number Diff line number Diff line Loading @@ -151,3 +151,7 @@ Bugfixes (:ticket:`23975`). * Made admin system checks run for custom ``AdminSite``\s (:ticket:`23497`). * Ensured the app registry is fully populated when unpickling models. When an external script (like a queueing infrastructure) reloads pickled models, it could crash with an ``AppRegistryNotReady`` exception (:ticket:`24007`).
tests/model_regress/tests.py +35 −0 Original line number Diff line number Diff line Loading @@ -2,7 +2,10 @@ from __future__ import unicode_literals import datetime from operator import attrgetter import pickle import subprocess import sys import tempfile import unittest from django.core.exceptions import ValidationError Loading Loading @@ -245,3 +248,35 @@ class EvaluateMethodTest(TestCase): dept = Department.objects.create(pk=1, name='abc') dept.evaluate = 'abc' Worker.objects.filter(department=dept) class ModelPickleTestCase(TestCase): def test_unpickling_when_appregistrynotready(self): """ #24007 -- Verifies that a pickled model can be unpickled without having to manually setup the apps registry beforehand. """ script_template = """#!/usr/bin/env python import pickle from django.conf import settings data = %r settings.configure(DEBUG=False, INSTALLED_APPS=('model_regress',), SECRET_KEY = "blah") article = pickle.loads(data) print(article.headline)""" a = Article.objects.create( headline="Some object", pub_date=datetime.datetime.now(), article_text="This is an article", ) with tempfile.NamedTemporaryFile(mode='w+', suffix=".py", dir='.', delete=True) as script: script.write(script_template % pickle.dumps(a)) script.flush() try: result = subprocess.check_output(['python', script.name]) except subprocess.CalledProcessError: self.fail("Unable to reload model pickled data") self.assertEqual(result.strip().decode(), "Some object")