Django Meta class abstract изменяется с True на False

Я понимаю, что когда класс наследует от абстрактной модели Django, он не наследует мета-атрибут abstract = True, что имеет смысл.

Однако в следующем примере от него ничего не унаследовано, но все же его Meta.abstract является False, хотя он определен как True:

from django.db import models
from django.db.models.base import ModelBase


class MyMeta(ModelBase):
    def __new__(cls, name, bases, attrs, **kwargs):
        """Check that all implemented (not abstract) classes have a foo attribute"""        
        Class = super().__new__(cls, name, bases, attrs, **kwargs)
        if not Class.Meta.abstract:
            print(Class)
            print('Class.Meta.ordering:', Class.Meta.ordering)  # Sanity check
            print('Class.Meta.abstract:', Class.Meta.abstract)
            if not hasattr(Class, 'foo'):
                raise NotImplementedError('Please add a foo attribute')
        return Class


class MyAbstractModel(models.Model, metaclass=MyMeta):
    name = models.CharField(max_length=250)

    class Meta:
        abstract = True
        ordering = ('-name',)

Prints:

<class 'myapp.models.base.MyAbstractModel'>
Class.Meta.ordering: -name
Class.Meta.abstract: False

Добавить поднимает (хотя он не должен поднимать, потому что это абстрактный класс):

NotImplementedError: Please add a foo attribute

Abstract - False, поскольку дочерние классы сами не становятся абстрактными классами. Вам нужно явно установить значение True. Информация об этом есть в документации. https://docs.djangoproject.com/en/4.1/topics/db/models/

You are accessing the wrong attribute, namely Class.Meta. Since this attribute will be inherited by any child classes Django actually modifies [GitHub] it for abstract models:

if abstract:
    # Abstract base models can't be instantiated and don't appear in
    # the list of models for an app. We do the final setup for them a
    # little differently from normal models.
    attr_meta.abstract = False
    new_class.Meta = attr_meta
    return new_class

Атрибут, который Django фактически использует за кулисами (все атрибуты правильно копируются в него), это _meta. Следовательно, если вы напишете следующее, вы получите ожидаемый результат:

if not Class._meta.abstract:
    ...
Вернуться на верх