Fixed #23750 -- Allowed core.checks.register to be used as a function

This commit is contained in:
averybigant 2014-11-05 14:01:49 +08:00 committed by Tim Graham
parent b3fd39f7c8
commit b7a5b6ab86
8 changed files with 71 additions and 14 deletions

View File

@ -561,6 +561,7 @@ answer newbie questions, and generally made Django that much better:
Raúl Cumplido <raulcumplido@gmail.com> Raúl Cumplido <raulcumplido@gmail.com>
Remco Wendt <remco.wendt@gmail.com> Remco Wendt <remco.wendt@gmail.com>
Renaud Parent <renaud.parent@gmail.com> Renaud Parent <renaud.parent@gmail.com>
Renbi Yu <averybigant@gmail.com>
Reza Mohammadi <reza@zeerak.ir> Reza Mohammadi <reza@zeerak.ir>
rhettg@gmail.com rhettg@gmail.com
Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com> Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com>

View File

@ -11,7 +11,7 @@ class SimpleAdminConfig(AppConfig):
verbose_name = _("Administration") verbose_name = _("Administration")
def ready(self): def ready(self):
checks.register(checks.Tags.admin)(check_admin_app) checks.register(check_admin_app, checks.Tags.admin)
class AdminConfig(SimpleAdminConfig): class AdminConfig(SimpleAdminConfig):

View File

@ -10,4 +10,4 @@ class AuthConfig(AppConfig):
verbose_name = _("Authentication and Authorization") verbose_name = _("Authentication and Authorization")
def ready(self): def ready(self):
checks.register(checks.Tags.models)(check_user_model) checks.register(check_user_model, checks.Tags.models)

View File

@ -9,4 +9,4 @@ class ContentTypesConfig(AppConfig):
verbose_name = _("Content Types") verbose_name = _("Content Types")
def ready(self): def ready(self):
checks.register(checks.Tags.models)(check_generic_foreign_keys) checks.register(check_generic_foreign_keys, checks.Tags.models)

View File

@ -23,11 +23,11 @@ class CheckRegistry(object):
self.registered_checks = [] self.registered_checks = []
self.deployment_checks = [] self.deployment_checks = []
def register(self, *tags, **kwargs): def register(self, check=None, *tags, **kwargs):
""" """
Decorator. Register given function `f` labeled with given `tags`. The Can be used as a function or a decorator. Register given function
function should receive **kwargs and return list of Errors and `f` labeled with given `tags`. The function should receive **kwargs
Warnings. and return list of Errors and Warnings.
Example:: Example::
@ -36,6 +36,8 @@ class CheckRegistry(object):
def my_check(apps, **kwargs): def my_check(apps, **kwargs):
# ... perform checks and collect `errors` ... # ... perform checks and collect `errors` ...
return errors return errors
# or
registry.register(my_check, 'mytag', 'anothertag')
""" """
kwargs.setdefault('deploy', False) kwargs.setdefault('deploy', False)
@ -49,6 +51,11 @@ class CheckRegistry(object):
self.registered_checks.append(check) self.registered_checks.append(check)
return check return check
if callable(check):
return inner(check)
else:
if check:
tags += (check, )
return inner return inner
def run_checks(self, app_configs=None, tags=None, include_deployment_checks=False): def run_checks(self, app_configs=None, tags=None, include_deployment_checks=False):

View File

@ -364,6 +364,11 @@ Signals
the request, was added to the :data:`~django.core.signals.request_started` the request, was added to the :data:`~django.core.signals.request_started`
signal. signal.
System Check Framework
^^^^^^^^^^^^^^^^^^^^^^
* :attr:`~django.core.checks.register` can now be used as a function.
Templates Templates
^^^^^^^^^ ^^^^^^^^^

View File

@ -151,6 +151,20 @@ settings file like this::
These checks will only be run if the :djadminopt:`--deploy` option is passed to These checks will only be run if the :djadminopt:`--deploy` option is passed to
the :djadmin:`check` command. the :djadmin:`check` command.
You can also use ``register`` as a function rather than a decorator by
passing a callable object (usually a function) as the first argument
to ``register``.
The code below is equivalent to the code above::
def my_check(app_configs, **kwargs):
...
register(my_check, Tags.security, deploy=True)
.. versionchanged:: 1.8
The ability to use register as a function was added.
.. _field-checking: .. _field-checking:
Field, Model, and Manager checks Field, Model, and Manager checks

View File

@ -31,17 +31,47 @@ class DummyObj(object):
class SystemCheckFrameworkTests(TestCase): class SystemCheckFrameworkTests(TestCase):
def test_register_and_run_checks(self): def test_register_and_run_checks(self):
calls = [0]
registry = CheckRegistry()
@registry.register()
def f(**kwargs): def f(**kwargs):
calls[0] += 1 calls[0] += 1
return [1, 2, 3] return [1, 2, 3]
def f2(**kwargs):
return [4, ]
def f3(**kwargs):
return [5, ]
calls = [0]
# test register as decorator
registry = CheckRegistry()
registry.register()(f)
registry.register("tag1", "tag2")(f2)
registry.register("tag2", deploy=True)(f3)
# test register as function
registry2 = CheckRegistry()
registry2.register(f)
registry2.register(f2, "tag1", "tag2")
registry2.register(f3, "tag2", deploy=True)
# check results
errors = registry.run_checks() errors = registry.run_checks()
self.assertEqual(errors, [1, 2, 3]) errors2 = registry2.run_checks()
self.assertEqual(calls[0], 1) self.assertEqual(errors, errors2)
self.assertEqual(sorted(errors), [1, 2, 3, 4])
self.assertEqual(calls[0], 2)
errors = registry.run_checks(tags=["tag1"])
errors2 = registry2.run_checks(tags=["tag1"])
self.assertEqual(errors, errors2)
self.assertEqual(sorted(errors), [4])
errors = registry.run_checks(tags=["tag1", "tag2"], include_deployment_checks=True)
errors2 = registry2.run_checks(tags=["tag1", "tag2"], include_deployment_checks=True)
self.assertEqual(errors, errors2)
self.assertEqual(sorted(errors), [4, 5])
class MessageTests(TestCase): class MessageTests(TestCase):