[Fixed]-Registering Django system checks in AppConfig's ready() method

15👍

From reading the examples on this page about the Apps Registry and System Checks Framework, it seems there are (at least) two ways to add your own System Checks. To adapt that page’s examples (assuming you’re creating an app called myapp):


1) Create a myapp/checks.py file like this:

from django.apps import apps as camelot_apps
from django.core.checks import register, Warning
from django.core.checks import Tags as DjangoTags

class Tags(DjangoTags):
    """Do this if none of the existing tags work for you:
    https://docs.djangoproject.com/en/1.8/ref/checks/#builtin-tags
    """
    my_new_tag = 'my_new_tag'

@register(Tags.my_new_tag)
def check_taggit_is_installed(app_configs=None, **kwargs):
    "Check that django-taggit is installed when usying myapp."
    errors = []
    try:
        from taggit import models
    except ImportError:
        errors.append(
            Warning(
                "The django-taggit app is required to use myapp.",
                hint=("Install django-taggit"),
                # A unique ID so it's easier to find this warning:
                id='myapp.W001',
            )
        )
    return errors

And then in myapp/__init__.py (create it if it doesn’t exist):

from . import checks

Running this should run that check above:

$ ./manage.py check myapp

2) Or, as I thought in my initial question, you can register that check in your AppConfig. So, keep the above code in myapp/check.py, but remove the @register(Tags.my_new_tag) line.

Then create myapp/apps.py containing this:

from django.core.checks import register
from .checks import Tags, check_taggit_is_installed

class MyappConfig(AppConfig):
    name = 'myapp'

    def ready(self):
        super(MyappConfig, self).ready()
        register(Tags.my_new_tag)(check_taggit_is_installed)

And alter myapps/__init__.py so it contains this:

from . import checks
default_app_config = 'myapp.apps.MyappConfig'

The first example seems simpler, with no need for a custom AppConfig.

13👍

Django recommends:

Checks should be registered in a file that’s loaded when your application is loaded; for example, in the AppConfig.ready() method.

Therefore, place the checks code in a checks.py file. Then simply in apps.py, as with signals:

from django.apps import AppConfig


class MyAppConfig(AppConfig):
    name = 'MyApp'
    verbose_name = "My App"

    def ready(self):
        # import myapp.signals
        import myapp.checks
👤Wtower

0👍

My guess is that you can just place this code in ready() method. For example of usage you can take a look at django.contrib.auth (or other contrib app). This app has check in checks.py file, that imported in apps.py and registered in ready() method: checks.py, apps.py.

👤f43d65

Leave a comment