[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)
相关推荐
数据智能老司机15 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机16 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机16 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机16 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i17 小时前
drf初步梳理
python·django
每日AI新事件17 小时前
python的异步函数
python
这里有鱼汤18 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python
databook1 天前
Manim实现脉冲闪烁特效
后端·python·动效
程序设计实验室1 天前
2025年了,在 Django 之外,Python Web 框架还能怎么选?
python
倔强青铜三1 天前
苦练Python第46天:文件写入与上下文管理器
人工智能·python·面试