系统检查框架¶
系统检查框架是一组用于验证Django项目的静态检查。它检测常见问题并提供如何修复它们的提示。框架是可扩展的,因此您可以轻松添加自己的检查。
可以通过 check
命令显式触发检查。检查在大多数命令(包括 runserver
和 migrate
)之前隐式触发。出于性能原因,检查不作为部署中使用的WSGI堆栈的一部分运行。如果需要在部署服务器上运行系统检查,请使用 check
明确触发它们。
严重的错误会阻止Django命令(如 runserver
)运行。次要问题会报告给控制台。如果您已检查警告的原因并且很乐意忽略它,则可以使用项目设置文件中的 SILENCED_SYSTEM_CHECKS
设置隐藏特定警告。
Django可以提出的所有检查的完整列表可以在 系统检查参考 中找到。
写你自己的支票¶
该框架是灵活的,并允许您编写函数执行任何其他类型的检查,你可能需要。以下是桩检查功能的示例:
from django.core.checks import Error, register
@register()
def example_check(app_configs, **kwargs):
errors = []
# ... your check logic here
if check_failed:
errors.append(
Error(
'an error',
hint='A hint.',
obj=checked_object,
id='myapp.E001',
)
)
return errors
检查函数 must 接受 app_configs
参数;这个参数是应该检查的应用程序的列表。如果为无,则必须在项目中已安装的 all 应用程序上运行检查。 **kwargs
参数是将来扩展所必需的。
消息¶
该函数必须返回消息列表。如果检查没有发现问题,则检查函数必须返回一个空列表。
check方法引发的警告和错误必须是 CheckMessage
的实例。 CheckMessage
的实例封装单个可报告的错误或警告。它还提供适用于消息的上下文和提示,以及用于过滤目的的唯一标识符。
这个概念非常类似于来自 消息框架 或 日志框架 的消息。消息使用指示消息严重性的 level
标记。
还有一些快捷方式可以使用公共级别创建邮件更容易。当使用这些类时,你可以省略 level
参数,因为它是类名的含义。
注册和标记检查¶
最后,您的检查功能必须使用系统检查注册表明确注册。检查应注册在加载应用程序时加载的文件中;例如,在 AppConfig.ready()
方法中。
-
register
(*tags)(function)¶
您可以根据需要向 register
传递尽可能多的标签,以便为您的支票加上标签。标记检查很有用,因为它允许您只运行一组特定的检查。例如,要注册兼容性检查,您将进行以下调用:
from django.core.checks import register, Tags
@register(Tags.compatibility)
def my_check(app_configs, **kwargs):
# ... perform compatibility checks and collect errors
return errors
您可以注册仅与如下所示的生产设置文件相关的“部署检查”:
@register(Tags.security, deploy=True)
def my_check(app_configs, **kwargs):
...
仅当使用 check --deploy
选项时,才会运行这些检查。
你也可以使用 register
作为一个函数,而不是一个装饰器通过传递一个可调用的对象(通常是一个函数)作为第一个参数到 register
。
下面的代码等同于上面的代码:
def my_check(app_configs, **kwargs):
...
register(my_check, Tags.security, deploy=True)
字段,模型,管理器和数据库检查¶
在某些情况下,您不需要注册您的支票功能 - 您可以搭载现有的注册。
字段,模型,模型管理器和数据库后端都实现已经向检查框架注册的 check()
方法。如果要添加额外的检查,您可以扩展对基类的实现,执行您需要的任何额外的检查,并将任何消息附加到基类生成的那些。建议您将每个检查委派给单独的方法。
添加了数据库后端检查。
考虑一个例子,你正在实现一个名为 RangedIntegerField
的自定义字段。此字段将 min
和 max
参数添加到 IntegerField
的构造函数。您可能需要添加一个检查,以确保用户提供的最小值小于或等于最大值。以下代码段显示了如何实现此检查:
from django.core import checks
from django.db import models
class RangedIntegerField(models.IntegerField):
def __init__(self, min=None, max=None, **kwargs):
super(RangedIntegerField, self).__init__(**kwargs)
self.min = min
self.max = max
def check(self, **kwargs):
# Call the superclass
errors = super(RangedIntegerField, self).check(**kwargs)
# Do some custom checks and add messages to `errors`:
errors.extend(self._check_min_max_values(**kwargs))
# Return all errors and warnings
return errors
def _check_min_max_values(self, **kwargs):
if (self.min is not None and
self.max is not None and
self.min > self.max):
return [
checks.Error(
'min greater than max.',
hint='Decrease min or increase max.',
obj=self,
id='myapp.E001',
)
]
# When no error, return an empty list
return []
如果你想添加检查到模型管理器,你将采取相同的方法在你的子类 Manager
。
如果要向模型类添加检查,该方法是 almost 相同的:唯一的区别是检查是类方法,而不是实例方法:
class MyModel(models.Model):
@classmethod
def check(cls, **kwargs):
errors = super(MyModel, cls).check(**kwargs)
# ... your own checks ...
return errors
写测试¶
消息是可比的。这允许你轻松地写测试:
from django.core.checks import Error
errors = checked_object.check()
expected_errors = [
Error(
'an error',
hint='A hint.',
obj=checked_object,
id='myapp.E001',
)
]
self.assertEqual(errors, expected_errors)