[1.8.x] Fixed #25686 -- Fixed crash on routers without an allow_migrate() method.
Thanks Simon Charette for review.
This commit is contained in:
parent
94d13415d8
commit
a42c5376e7
|
@ -326,30 +326,35 @@ class ConnectionRouter(object):
|
|||
method = router.allow_migrate
|
||||
except AttributeError:
|
||||
method = router.allow_syncdb
|
||||
has_deprecated_signature = True
|
||||
warnings.warn(
|
||||
'Router.allow_syncdb has been deprecated and will stop working in Django 1.9. '
|
||||
'Rename the method to allow_migrate.',
|
||||
RemovedInDjango19Warning, stacklevel=2)
|
||||
else:
|
||||
if HAS_INSPECT_SIGNATURE:
|
||||
sig = inspect.signature(method)
|
||||
has_deprecated_signature = not any(
|
||||
p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values()
|
||||
)
|
||||
else:
|
||||
argspec = inspect.getargspec(method)
|
||||
has_deprecated_signature = len(argspec.args) == 3 and not argspec.keywords
|
||||
if has_deprecated_signature:
|
||||
# Raised here because allow_syncdb has to be called with
|
||||
# the deprecated signature but shouldn't show this
|
||||
# warning (only the deprecated method one)
|
||||
warnings.warn(
|
||||
"The signature of allow_migrate has changed from "
|
||||
"allow_migrate(self, db, model) to "
|
||||
"allow_migrate(self, db, app_label, model_name=None, **hints). "
|
||||
"Support for the old signature will be removed in Django 1.10.",
|
||||
RemovedInDjango110Warning)
|
||||
except AttributeError:
|
||||
# If the router doesn't have a method, skip to the next one.
|
||||
continue
|
||||
|
||||
if HAS_INSPECT_SIGNATURE:
|
||||
sig = inspect.signature(router.allow_migrate)
|
||||
has_deprecated_signature = not any(
|
||||
p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values()
|
||||
)
|
||||
else:
|
||||
argspec = inspect.getargspec(router.allow_migrate)
|
||||
has_deprecated_signature = len(argspec.args) == 3 and not argspec.keywords
|
||||
|
||||
if has_deprecated_signature:
|
||||
warnings.warn(
|
||||
"The signature of allow_migrate has changed from "
|
||||
"allow_migrate(self, db, model) to "
|
||||
"allow_migrate(self, db, app_label, model_name=None, **hints). "
|
||||
"Support for the old signature will be removed in Django 1.10.",
|
||||
RemovedInDjango110Warning)
|
||||
model = hints.get('model')
|
||||
allow = None if model is None else method(db, model)
|
||||
else:
|
||||
|
|
|
@ -12,4 +12,5 @@ Bugfixes
|
|||
* Fixed a crash of the debug view during the autumn DST change when
|
||||
:setting:`USE_TZ` is ``False`` and ``pytz`` is installed.
|
||||
|
||||
* ...
|
||||
* Fixed a regression in 1.8.6 that caused database routers without an
|
||||
``allow_migrate()`` method to crash (:ticket:`25686`).
|
||||
|
|
|
@ -956,6 +956,27 @@ class RouterTestCase(TestCase):
|
|||
self.assertTrue(router.allow_migrate('default', 'app_label'))
|
||||
self.assertEqual(force_text(recorded.pop().message), msg)
|
||||
|
||||
def test_allow_syncdb_deprecation(self):
|
||||
class LegacyRouter(object):
|
||||
def allow_syncdb(self, db, model):
|
||||
assert db == 'default'
|
||||
assert model is User
|
||||
return True
|
||||
|
||||
with override_settings(DATABASE_ROUTERS=[LegacyRouter()]):
|
||||
with warnings.catch_warnings(record=True) as recorded:
|
||||
warnings.filterwarnings('always')
|
||||
msg = (
|
||||
"Router.allow_syncdb has been deprecated and will stop "
|
||||
"working in Django 1.9. Rename the method to allow_migrate."
|
||||
)
|
||||
self.assertTrue(router.allow_migrate_model('default', User))
|
||||
self.assertEqual(force_text(recorded.pop().message), msg)
|
||||
self.assertEqual(recorded, [])
|
||||
|
||||
self.assertTrue(router.allow_migrate('default', 'app_label'))
|
||||
self.assertEqual(force_text(recorded.pop().message), msg)
|
||||
|
||||
def test_partial_router(self):
|
||||
"A router can choose to implement a subset of methods"
|
||||
dive = Book.objects.using('other').create(title="Dive into Python",
|
||||
|
|
Loading…
Reference in New Issue