[Django 0-1] Core.Checks 模块

Checks 源码分析

Django 的 checks 模块提供了一系列的检查函数,用于检查 Django 项目的配置是否正确。

文件结构

shell 复制代码
.
├── __init__.py
├── async_checks.py
├── caches.py
├── compatibility
│   ├── __init__.py
│   └── django_4_0.py
├── database.py
├── files.py
├── messages.py
├── model_checks.py
├── registry.py
├── security
│   ├── __init__.py
│   ├── base.py
│   ├── csrf.py
│   └── sessions.py
├── templates.py
├── translation.py
└── urls.py

3 directories, 17 files

可以学习的地方

  • 对项目的可靠性检查方面可以借鉴 Django 的设计,可以包括

    • 内置的 contrib 如 admin
    • async_support 特性检查,如是否在不支持的环境下开启了异步支持
    • 缓存配置检查,如是否使用了过期时间短的缓存
    • 数据库配置检查,如是否使用了过期时间短的数据库连接
    • 模型检查,如是否有重复的模型名称
    • 安全检查,如是否开启了 CSRF 保护,是否使用了过期时间短的 session
    • 模板检查
    • 翻译检查
    • URL 检查
    • siangls 检查
    • files 文件系统检查
  • 使用inspect.func_accepts_kwargs函数,强制让函数参数中包含**kwargs

    同样的函数还有func_accepts_var_args,强制让函数参数中包含*args
    func_supports_parameter置顶

  • core/checks/registry.py CheckRegistry 类方法提供了利用装饰器机制封装了函数register用于注册检查。

python 复制代码
class CheckRegistry:

    def __init__(self):
        self.registered_checks = set()
        self.deployment_checks = set()

    def register(self, check=None, *tags, **kwargs):
        """
        Can be used as a function or a decorator. Register given function
        `f` labeled with given `tags`. The function should receive **kwargs
        and return list of Errors and Warnings.

        Example::

            registry = CheckRegistry()
            @registry.register('mytag', 'anothertag')
            def my_check(app_configs, **kwargs):
                # ... perform checks and collect `errors` ...
                return errors
            # or
            registry.register(my_check, 'mytag', 'anothertag')
        """

        def inner(check):
            if not func_accepts_kwargs(check):
                raise TypeError(
                    "Check functions must accept keyword arguments (**kwargs)."
                )
            check.tags = tags
            checks = (
                self.deployment_checks
                if kwargs.get("deploy")
                else self.registered_checks
            )
            checks.add(check)
            return check

        # 如果你的check函数是一个callable对象,那么直接返回inner(check)
        if callable(check):
            return inner(check)
        else:
            if check:
                tags += (check,)
            return inner
  • 为项目建立一个 runtime 检查机制,通过这些 checks 来确保项目的运行正确。

id 可以确保所有 errors 和 warnings 的唯一性,并提供一种过滤 id 和 level 机制来忽略特定的错误。

python 复制代码
class CheckMessage:
    def __init__(self, level, msg, hint=None, obj=None, id=None):
        if not isinstance(level, int):
            raise TypeError("The first argument should be level.")
        self.level = level
        self.msg = msg
        self.hint = hint
        self.obj = obj
        self.id = id

    def __eq__(self, other):
        return isinstance(other, self.__class__) and all(
            getattr(self, attr) == getattr(other, attr)
            for attr in ["level", "msg", "hint", "obj", "id"]
        )

    def __str__(self):
        from django.db import models

        if self.obj is None:
            obj = "?"
        elif isinstance(self.obj, models.base.ModelBase):
            # We need to hardcode ModelBase and Field cases because its __str__
            # method doesn't return "applabel.modellabel" and cannot be changed.
            obj = self.obj._meta.label
        else:
            obj = str(self.obj)
        id = "(%s) " % self.id if self.id else ""
        hint = "\n\tHINT: %s" % self.hint if self.hint else ""
        return "%s: %s%s%s" % (obj, id, self.msg, hint)

    def __repr__(self):
        return "<%s: level=%r, msg=%r, hint=%r, obj=%r, id=%r>" % (
            self.__class__.__name__,
            self.level,
            self.msg,
            self.hint,
            self.obj,
            self.id,
        )

    def is_serious(self, level=ERROR):
        return self.level >= level

    def is_silenced(self):
        from django.conf import settings

        return self.id in settings.SILENCED_SYSTEM_CHECKS


class Debug(CheckMessage):
    def __init__(self, *args, **kwargs):
        super().__init__(DEBUG, *args, **kwargs)


class Info(CheckMessage):
    def __init__(self, *args, **kwargs):
        super().__init__(INFO, *args, **kwargs)


class Warning(CheckMessage):
    def __init__(self, *args, **kwargs):
        super().__init__(WARNING, *args, **kwargs)


class Error(CheckMessage):
    def __init__(self, *args, **kwargs):
        super().__init__(ERROR, *args, **kwargs)


class Critical(CheckMessage):
    def __init__(self, *args, **kwargs):
        super().__init__(CRITICAL, *args, **kwargs)
相关推荐
萧鼎1 小时前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
学地理的小胖砸1 小时前
【一些关于Python的信息和帮助】
开发语言·python
疯一样的码农1 小时前
Python 继承、多态、封装、抽象
开发语言·python
Wx-bishekaifayuan1 小时前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
Python大数据分析@2 小时前
python操作CSV和excel,如何来做?
开发语言·python·excel
黑叶白树2 小时前
简单的签到程序 python笔记
笔记·python
Shy9604182 小时前
Bert完形填空
python·深度学习·bert
上海_彭彭2 小时前
【提效工具开发】Python功能模块执行和 SQL 执行 需求整理
开发语言·python·sql·测试工具·element
zhongcx012 小时前
使用Python查找大文件的实用脚本
python
yyfhq3 小时前
sdnet
python