Loading django/db/models/base.py +2 −0 Original line number Diff line number Diff line Loading @@ -1658,6 +1658,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/test_pickle.py +35 −0 Original line number Diff line number Diff line import datetime import pickle import subprocess import tempfile import warnings from django.db import models, DJANGO_VERSION_PICKLE_KEY Loading @@ -6,6 +9,8 @@ from django.test import TestCase from django.utils.encoding import force_text from django.utils.version import get_major_version, get_version from .models import Article class ModelPickleTestCase(TestCase): def test_missing_django_version_unpickling(self): Loading Loading @@ -51,3 +56,33 @@ class ModelPickleTestCase(TestCase): "Pickled model instance's Django version %s does not " "match the current version %s." % (str(float(get_major_version()) - 0.1), get_version())) 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 @@ -1658,6 +1658,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/test_pickle.py +35 −0 Original line number Diff line number Diff line import datetime import pickle import subprocess import tempfile import warnings from django.db import models, DJANGO_VERSION_PICKLE_KEY Loading @@ -6,6 +9,8 @@ from django.test import TestCase from django.utils.encoding import force_text from django.utils.version import get_major_version, get_version from .models import Article class ModelPickleTestCase(TestCase): def test_missing_django_version_unpickling(self): Loading Loading @@ -51,3 +56,33 @@ class ModelPickleTestCase(TestCase): "Pickled model instance's Django version %s does not " "match the current version %s." % (str(float(get_major_version()) - 0.1), get_version())) 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")