简体   繁体   English

如何在我的 Django 模型中强制执行 inheritance?

[英]How can I enforce inheritance in my Django models?

In my Django app, I have an abstract model called MyModel that has eg created_at and updated_at fields.在我的 Django 应用程序中,我有一个名为MyModel的抽象 model,它具有例如created_atupdated_at字段。 I want all the models in my project to subclass MyModel rather than using django.db.models.Model directly.我希望我项目中的所有模型都是MyModel的子类,而不是直接使用django.db.models.Model

We have several developers on our app, so I want to use some sort of linter or CI check to enforce that this happens.我们的应用程序上有几个开发人员,所以我想使用某种 linter 或 CI 检查来强制执行此操作。 How can I do this?我怎样才能做到这一点?

As mentioned by Willem Van Onsem in their comment you can write your own checks using the System check framework .正如Willem Van Onsem 在他们的评论中提到的,您可以使用系统检查框架编写自己的检查。

Assuming we have the following models in an app named "checktest" with Parent being the model that all models should inherit from:假设我们在名为“checktest”的应用程序中有以下模型, Parent是所有模型都应继承的 model:

from django.db import models


class Parent(models.Model):
    class Meta:
        abstract = True


# This should raise an error
class Foo(models.Model):
    pass


# This should be fine
class Bar(Parent):
    pass

We'll write a check as follows in a file checktest/custom_checks.py , note that the list APPS_TO_TEST contains the names of the apps whose models should inherit from the parent class:我们将在文件checktest/custom_checks.py中编写如下检查,注意列表APPS_TO_TEST包含其模型应从父 class 继承的应用程序的名称:

from django.apps import apps
from django.core.checks import Error, register, Tags
from .models import Parent

# List of apps that should inherit from Parent
APPS_TO_TEST = ["checktest"]


@register(Tags.models)
def model_must_inherit(app_configs, **kwargs):
    errors = []
    for app in APPS_TO_TEST:
        models = apps.get_app_config(app).get_models()
        for model in models:
            if not issubclass(model, Parent):
                errors.append(Error(
                    f"Model {model.__name__} does not inherit from Parent",
                    hint="Models must inherit from the Parent class",
                    obj=model,
                    id="checktest.E001"
                ))
    return errors

In the app configs ready method we'll import the above file so that the check will get run:在 app configs ready方法中,我们将导入上述文件,以便运行检查:

from django.apps import AppConfig


class ChecktestConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'checktest'

    def ready(self) -> None:
        from . import custom_checks

Now whenever we run commands like runserver or migrate the checks will get implicitly run.现在,每当我们运行诸如runservermigrate之类的命令时,检查都会隐式运行。 In a CI environment you can explicitly run the checks using the check command.在 CI 环境中,您可以使用check命令显式运行检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM