Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Registering Django system checks in AppConfig's ready() method

Tags:

django

In the docs for Django's System check framework it says:

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

None of the examples on that page, or around the AppConfig.ready() method, show how to do this. Given a checking method like:

from django.core.checks import register, Tags

@register(Tags.compatibility)
def my_check(app_configs, **kwargs):
    # ... perform compatibility checks and collect errors
    return errors

How would you do this in/from the AppConfig.ready() method? Is one called from the other? Which file should the above method go in? Do you add @register(...) to the ready() method?

like image 254
Phil Gyford Avatar asked Jul 24 '15 20:07

Phil Gyford


2 Answers

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.

like image 92
Phil Gyford Avatar answered Nov 13 '22 05:11

Phil Gyford


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
like image 33
Wtower Avatar answered Nov 13 '22 07:11

Wtower



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!